• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/include/ucode/types.h

  1 /*
  2  * Copyright (C) 2021 Jo-Philipp Wich <jo@mein.io>
  3  *
  4  * Permission to use, copy, modify, and/or distribute this software for any
  5  * purpose with or without fee is hereby granted, provided that the above
  6  * copyright notice and this permission notice appear in all copies.
  7  *
  8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15  */
 16 
 17 #ifndef UCODE_TYPES_H
 18 #define UCODE_TYPES_H
 19 
 20 #include <stdbool.h>
 21 #include <stdint.h>
 22 #include <regex.h>
 23 #include <json-c/json.h>
 24 
 25 #include "util.h"
 26 
 27 
 28 /* Value types and generic value header */
 29 
 30 typedef enum uc_type {
 31         UC_NULL,
 32         UC_INTEGER,
 33         UC_BOOLEAN,
 34         UC_STRING,
 35         UC_DOUBLE,
 36         UC_ARRAY,
 37         UC_OBJECT,
 38         UC_REGEXP,
 39         UC_CFUNCTION,
 40         UC_CLOSURE,
 41         UC_UPVALUE,
 42         UC_RESOURCE,
 43         UC_PROGRAM,
 44         UC_SOURCE
 45 } uc_type_t;
 46 
 47 typedef struct uc_value {
 48         uint32_t type:4;
 49         uint32_t mark:1;
 50         uint32_t u64_or_constant:1;
 51         uint32_t refcount:26;
 52 } uc_value_t;
 53 
 54 
 55 /* Constant list defintions */
 56 
 57 typedef struct {
 58         size_t isize;
 59         size_t dsize;
 60         uint64_t *index;
 61         char *data;
 62 } uc_value_list_t;
 63 
 64 
 65 /* Source buffer defintions */
 66 
 67 uc_declare_vector(uc_lineinfo_t, uint8_t);
 68 
 69 typedef struct {
 70         uc_value_t header;
 71         char *filename, *runpath, *buffer;
 72         FILE *fp;
 73         size_t off;
 74         uc_lineinfo_t lineinfo;
 75         struct {
 76                 size_t count, offset;
 77                 uc_value_t **entries;
 78         } exports;
 79 } uc_source_t;
 80 
 81 
 82 /* Bytecode chunk defintions */
 83 
 84 typedef struct {
 85         size_t from, to, target, slot;
 86 } uc_ehrange_t;
 87 
 88 typedef struct {
 89         size_t from, to, slot, nameidx;
 90 } uc_varrange_t;
 91 
 92 uc_declare_vector(uc_ehranges_t, uc_ehrange_t);
 93 uc_declare_vector(uc_variables_t, uc_varrange_t);
 94 uc_declare_vector(uc_offsetinfo_t, uint8_t);
 95 
 96 typedef struct {
 97         size_t count;
 98         uint8_t *entries;
 99         uc_ehranges_t ehranges;
100         struct {
101                 uc_variables_t variables;
102                 uc_value_list_t varnames;
103                 uc_offsetinfo_t offsets;
104         } debuginfo;
105 } uc_chunk_t;
106 
107 
108 /* Value type structures */
109 
110 typedef struct uc_weakref {
111         struct uc_weakref *prev;
112         struct uc_weakref *next;
113 } uc_weakref_t;
114 
115 typedef struct uc_function {
116         uc_weakref_t progref;
117         bool arrow, vararg, strict, module;
118         size_t nargs;
119         size_t nupvals;
120         size_t srcidx;
121         size_t srcpos;
122         uc_chunk_t chunk;
123         struct uc_program *program;
124         char name[];
125 } uc_function_t;
126 
127 typedef struct {
128         uc_value_t header;
129         double dbl;
130 } uc_double_t;
131 
132 typedef struct {
133         uc_value_t header;
134         union {
135                 int64_t s64;
136                 uint64_t u64;
137         } i;
138 } uc_integer_t;
139 
140 typedef struct {
141         uc_value_t header;
142         size_t length;
143         char str[];
144 } uc_string_t;
145 
146 typedef struct {
147         uc_value_t header;
148         uc_weakref_t ref;
149         size_t count;
150         uc_value_t *proto;
151         uc_value_t **entries;
152 } uc_array_t;
153 
154 typedef struct {
155         uc_value_t header;
156         uc_weakref_t ref;
157         uc_value_t *proto;
158         struct lh_table *table;
159 } uc_object_t;
160 
161 typedef struct {
162         uc_value_t header;
163         regex_t regexp;
164         bool icase, newline, global;
165         char source[];
166 } uc_regexp_t;
167 
168 typedef struct uc_upval_tref {
169         uc_value_t header;
170         size_t slot;
171         bool closed;
172         uc_value_t *value;
173         struct uc_upval_tref *next;
174 } uc_upvalref_t;
175 
176 typedef struct {
177         uc_value_t header;
178         uc_weakref_t ref;
179         bool is_arrow;
180         uc_function_t *function;
181         uc_upvalref_t **upvals;
182 } uc_closure_t;
183 
184 typedef struct uc_vm uc_vm_t;
185 typedef uc_value_t *(*uc_cfn_ptr_t)(uc_vm_t *, size_t);
186 
187 typedef struct {
188         uc_value_t header;
189         uc_cfn_ptr_t cfn;
190         char name[];
191 } uc_cfunction_t;
192 
193 typedef struct {
194         const char *name;
195         uc_value_t *proto;
196         void (*free)(void *);
197 } uc_resource_type_t;
198 
199 typedef struct {
200         uc_value_t header;
201         uc_resource_type_t *type;
202         void *data;
203 } uc_resource_t;
204 
205 uc_declare_vector(uc_resource_types_t, uc_resource_type_t *);
206 
207 
208 /* Program structure definitions */
209 
210 uc_declare_vector(uc_sources_t, uc_source_t *);
211 uc_declare_vector(uc_modexports_t, uc_upvalref_t *);
212 
213 typedef struct uc_program {
214         uc_value_t header;
215         uc_value_list_t constants;
216         uc_weakref_t functions;
217         uc_sources_t sources;
218         uc_modexports_t exports;
219 } uc_program_t;
220 
221 
222 /* Parser definitions */
223 
224 uc_declare_vector(uc_search_path_t, char *);
225 
226 typedef struct {
227         bool lstrip_blocks;
228         bool trim_blocks;
229         bool strict_declarations;
230         bool raw_mode;
231         uc_search_path_t module_search_path;
232         uc_search_path_t force_dynlink_list;
233 } uc_parse_config_t;
234 
235 extern uc_parse_config_t uc_default_parse_config;
236 
237 void uc_search_path_init(uc_search_path_t *search_path);
238 
239 static inline void
240 uc_search_path_add(uc_search_path_t *search_path, char *path) {
241         uc_vector_push(search_path, xstrdup(path));
242 }
243 
244 static inline void
245 uc_search_path_free(uc_search_path_t *search_path) {
246         while (search_path->count > 0)
247                 free(search_path->entries[--search_path->count]);
248 
249         uc_vector_clear(search_path);
250 }
251 
252 
253 /* VM definitions */
254 
255 typedef enum {
256         EXCEPTION_NONE,
257         EXCEPTION_SYNTAX,
258         EXCEPTION_RUNTIME,
259         EXCEPTION_TYPE,
260         EXCEPTION_REFERENCE,
261         EXCEPTION_USER,
262         EXCEPTION_EXIT
263 } uc_exception_type_t;
264 
265 typedef struct {
266         uc_exception_type_t type;
267         uc_value_t *stacktrace;
268         char *message;
269 } uc_exception_t;
270 
271 typedef struct {
272         uint8_t *ip;
273         uc_closure_t *closure;
274         uc_cfunction_t *cfunction;
275         size_t stackframe;
276         uc_value_t *ctx;
277         bool mcall, strict;
278 } uc_callframe_t;
279 
280 uc_declare_vector(uc_callframes_t, uc_callframe_t);
281 uc_declare_vector(uc_stack_t, uc_value_t *);
282 
283 typedef struct printbuf uc_stringbuf_t;
284 
285 typedef void (uc_exception_handler_t)(uc_vm_t *, uc_exception_t *);
286 
287 struct uc_vm {
288         uc_stack_t stack;
289         uc_exception_t exception;
290         uc_callframes_t callframes;
291         uc_upvalref_t *open_upvals;
292         uc_parse_config_t *config;
293         uc_value_t *globals;
294         uc_value_t *registry;
295         uc_source_t *sources;
296         uc_weakref_t values;
297         uc_resource_types_t restypes;
298         char _reserved[sizeof(uc_modexports_t)];
299         union {
300                 uint32_t u32;
301                 int32_t s32;
302                 uint16_t u16;
303                 int16_t s16;
304                 uint8_t u8;
305                 int8_t s8;
306         } arg;
307         size_t alloc_refs;
308         uint8_t trace;
309         uint8_t gc_flags;
310         uint16_t gc_interval;
311         uc_stringbuf_t *strbuf;
312         uc_exception_handler_t *exhandler;
313         FILE *output;
314 };
315 
316 
317 /* Value API */
318 
319 __hidden void ucv_free(uc_value_t *, bool);
320 __hidden void ucv_unref(uc_weakref_t *);
321 __hidden void ucv_ref(uc_weakref_t *, uc_weakref_t *);
322 
323 uc_value_t *ucv_get(uc_value_t *uv);
324 void ucv_put(uc_value_t *);
325 
326 uc_type_t ucv_type(uc_value_t *);
327 const char *ucv_typename(uc_value_t *);
328 
329 uc_value_t *ucv_boolean_new(bool);
330 bool ucv_boolean_get(uc_value_t *);
331 
332 uc_value_t *ucv_string_new(const char *);
333 uc_value_t *ucv_string_new_length(const char *, size_t);
334 size_t ucv_string_length(uc_value_t *);
335 
336 char *_ucv_string_get(uc_value_t **);
337 #define ucv_string_get(uv) _ucv_string_get((uc_value_t **)&uv)
338 
339 uc_stringbuf_t *ucv_stringbuf_new(void);
340 uc_value_t *ucv_stringbuf_finish(uc_stringbuf_t *);
341 
342 void _ucv_stringbuf_append(uc_stringbuf_t *, const char *, size_t);
343 
344 #define _ucv_is_literal(str) ("" str)
345 #define ucv_stringbuf_append(buf, str) _ucv_stringbuf_append(buf, _ucv_is_literal(str), sizeof(str) - 1)
346 #define ucv_stringbuf_addstr(buf, str, len) _ucv_stringbuf_append(buf, str, len)
347 #define ucv_stringbuf_printf(buf, fmt, ...) sprintbuf(buf, fmt, __VA_ARGS__)
348 
349 uc_value_t *ucv_int64_new(int64_t);
350 uc_value_t *ucv_uint64_new(uint64_t);
351 int64_t ucv_int64_get(uc_value_t *);
352 uint64_t ucv_uint64_get(uc_value_t *);
353 
354 uc_value_t *ucv_double_new(double);
355 double ucv_double_get(uc_value_t *);
356 
357 uc_value_t *ucv_array_new(uc_vm_t *);
358 uc_value_t *ucv_array_new_length(uc_vm_t *, size_t);
359 uc_value_t *ucv_array_get(uc_value_t *, size_t);
360 uc_value_t *ucv_array_pop(uc_value_t *);
361 uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *);
362 uc_value_t *ucv_array_shift(uc_value_t *);
363 uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *);
364 void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *));
365 bool ucv_array_delete(uc_value_t *, size_t, size_t);
366 bool ucv_array_set(uc_value_t *, size_t, uc_value_t *);
367 size_t ucv_array_length(uc_value_t *);
368 
369 uc_value_t *ucv_object_new(uc_vm_t *);
370 uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *);
371 bool ucv_object_add(uc_value_t *, const char *, uc_value_t *);
372 void ucv_object_sort(uc_value_t *, int (*)(const void *, const void *));
373 bool ucv_object_delete(uc_value_t *, const char *);
374 size_t ucv_object_length(uc_value_t *);
375 
376 #define ucv_object_foreach(obj, key, val)                                                                                                               \
377         char *key = NULL;                                                                                                                                                       \
378         uc_value_t *val = NULL;                                                                                                                                         \
379         struct lh_entry *entry##key;                                                                                                                            \
380         struct lh_entry *entry_next##key = NULL;                                                                                                        \
381         for (entry##key = (ucv_type(obj) == UC_OBJECT) ? ((uc_object_t *)obj)->table->head : NULL;      \
382              (entry##key ? (key = (char *)lh_entry_k(entry##key),                                                                       \
383                             val = (uc_value_t *)lh_entry_v(entry##key),                                                         \
384                             entry_next##key = entry##key->next, entry##key)                                                     \
385                          : 0);                                                                                                                                          \
386              entry##key = entry_next##key)
387 
388 uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t);
389 
390 uc_value_t *ucv_closure_new(uc_vm_t *, uc_function_t *, bool);
391 
392 uc_resource_type_t *ucv_resource_type_add(uc_vm_t *, const char *, uc_value_t *, void (*)(void *));
393 uc_resource_type_t *ucv_resource_type_lookup(uc_vm_t *, const char *);
394 
395 uc_value_t *ucv_resource_new(uc_resource_type_t *, void *);
396 void *ucv_resource_data(uc_value_t *uv, const char *);
397 void **ucv_resource_dataptr(uc_value_t *, const char *);
398 
399 uc_value_t *ucv_regexp_new(const char *, bool, bool, bool, char **);
400 
401 uc_value_t *ucv_upvalref_new(size_t);
402 
403 uc_value_t *ucv_prototype_get(uc_value_t *);
404 bool ucv_prototype_set(uc_value_t *, uc_value_t *);
405 
406 uc_value_t *ucv_property_get(uc_value_t *, const char *);
407 
408 uc_value_t *ucv_from_json(uc_vm_t *, json_object *);
409 json_object *ucv_to_json(uc_value_t *);
410 
411 char *ucv_to_string(uc_vm_t *, uc_value_t *);
412 char *ucv_to_jsonstring_formatted(uc_vm_t *, uc_value_t *, char, size_t);
413 void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_t, char, size_t);
414 
415 #define ucv_to_jsonstring(vm, val) ucv_to_jsonstring_formatted(vm, val, '\1', 0)
416 #define ucv_to_stringbuf(vm, buf, val, json) ucv_to_stringbuf_formatted(vm, buf, val, 0, json ? '\1' : '\0', 0)
417 
418 uc_type_t ucv_cast_number(uc_value_t *, int64_t *, double *);
419 
420 uc_value_t *ucv_to_number(uc_value_t *);
421 
422 static inline double
423 ucv_to_double(uc_value_t *v)
424 {
425         uc_value_t *nv;
426         double d;
427 
428         nv = ucv_to_number(v);
429         d = ucv_double_get(nv);
430         ucv_put(nv);
431 
432         return d;
433 }
434 
435 static inline int64_t
436 ucv_to_integer(uc_value_t *v)
437 {
438         uc_value_t *nv;
439         int64_t n;
440 
441         nv = ucv_to_number(v);
442         n = ucv_int64_get(nv);
443         ucv_put(nv);
444 
445         return n;
446 }
447 
448 static inline uint64_t
449 ucv_to_unsigned(uc_value_t *v)
450 {
451         uc_value_t *nv;
452         uint64_t u;
453 
454         nv = ucv_to_number(v);
455         u = ucv_uint64_get(nv);
456         ucv_put(nv);
457 
458         return u;
459 }
460 
461 static inline bool
462 ucv_is_callable(uc_value_t *uv)
463 {
464         switch (ucv_type(uv)) {
465         case UC_CLOSURE:
466         case UC_CFUNCTION:
467                 return true;
468 
469         default:
470                 return false;
471         }
472 }
473 
474 static inline bool
475 ucv_is_arrowfn(uc_value_t *uv)
476 {
477         uc_closure_t *closure = (uc_closure_t *)uv;
478 
479         return (ucv_type(uv) == UC_CLOSURE && closure->is_arrow);
480 }
481 
482 static inline bool
483 ucv_is_u64(uc_value_t *uv)
484 {
485         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64_or_constant == true &&
486                     uv->type == UC_INTEGER);
487 }
488 
489 static inline bool
490 ucv_is_constant(uc_value_t *uv)
491 {
492         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64_or_constant == true &&
493                 (uv->type == UC_ARRAY || uv->type == UC_OBJECT));
494 }
495 
496 static inline bool
497 ucv_set_constant(uc_value_t *uv, bool constant)
498 {
499         if (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64_or_constant != constant &&
500             (uv->type == UC_ARRAY || uv->type == UC_OBJECT)) {
501                 uv->u64_or_constant = constant;
502 
503                 return true;
504         }
505 
506         return false;
507 }
508 
509 static inline bool
510 ucv_is_scalar(uc_value_t *uv)
511 {
512         switch (ucv_type(uv)) {
513         case UC_NULL:
514         case UC_BOOLEAN:
515         case UC_DOUBLE:
516         case UC_INTEGER:
517         case UC_STRING:
518                 return true;
519 
520         default:
521                 return false;
522         }
523 }
524 
525 bool ucv_is_equal(uc_value_t *, uc_value_t *);
526 bool ucv_is_truish(uc_value_t *);
527 
528 bool ucv_compare(int, uc_value_t *, uc_value_t *, int *);
529 
530 uc_value_t *ucv_key_get(uc_vm_t *, uc_value_t *, uc_value_t *);
531 uc_value_t *ucv_key_set(uc_vm_t *, uc_value_t *, uc_value_t *, uc_value_t *);
532 bool ucv_key_delete(uc_vm_t *, uc_value_t *, uc_value_t *);
533 
534 
535 static inline bool
536 ucv_is_marked(uc_value_t *uv)
537 {
538         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->mark == true);
539 }
540 
541 static inline void
542 ucv_set_mark(uc_value_t *uv)
543 {
544         if (((uintptr_t)uv & 3) == 0 && uv != NULL)
545                 uv->mark = true;
546 }
547 
548 static inline void
549 ucv_clear_mark(uc_value_t *uv)
550 {
551         if (((uintptr_t)uv & 3) == 0 && uv != NULL)
552                 uv->mark = false;
553 }
554 
555 void ucv_gc(uc_vm_t *);
556 
557 __hidden void ucv_freeall(uc_vm_t *);
558 
559 #endif /* UCODE_TYPES_H */
560 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt