• 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 <signal.h>
 24 #include <json-c/json.h>
 25 
 26 #include "util.h"
 27 #include "platform.h"
 28 
 29 
 30 /* Value types and generic value header */
 31 
 32 typedef enum uc_type {
 33         UC_NULL,
 34         UC_INTEGER,
 35         UC_BOOLEAN,
 36         UC_STRING,
 37         UC_DOUBLE,
 38         UC_ARRAY,
 39         UC_OBJECT,
 40         UC_REGEXP,
 41         UC_CFUNCTION,
 42         UC_CLOSURE,
 43         UC_UPVALUE,
 44         UC_RESOURCE,
 45         UC_PROGRAM,
 46         UC_SOURCE
 47 } uc_type_t;
 48 
 49 typedef struct uc_value {
 50         uint32_t type:4;
 51         uint32_t mark:1;
 52         uint32_t ext_flag:1;
 53         uint32_t refcount:26;
 54 } uc_value_t;
 55 
 56 
 57 /* Constant list defintions */
 58 
 59 typedef struct {
 60         size_t isize;
 61         size_t dsize;
 62         uint64_t *index;
 63         char *data;
 64 } uc_value_list_t;
 65 
 66 
 67 /* Source buffer defintions */
 68 
 69 uc_declare_vector(uc_lineinfo_t, uint8_t);
 70 
 71 typedef struct {
 72         uc_value_t header;
 73         char *filename, *runpath, *buffer;
 74         FILE *fp;
 75         size_t off;
 76         uc_lineinfo_t lineinfo;
 77         struct {
 78                 size_t count, offset;
 79                 uc_value_t **entries;
 80         } exports;
 81 } uc_source_t;
 82 
 83 
 84 /* Bytecode chunk defintions */
 85 
 86 typedef struct {
 87         size_t from, to, target, slot;
 88 } uc_ehrange_t;
 89 
 90 typedef struct {
 91         size_t from, to, slot, nameidx;
 92 } uc_varrange_t;
 93 
 94 uc_declare_vector(uc_ehranges_t, uc_ehrange_t);
 95 uc_declare_vector(uc_variables_t, uc_varrange_t);
 96 uc_declare_vector(uc_offsetinfo_t, uint8_t);
 97 
 98 typedef struct {
 99         size_t count;
100         uint8_t *entries;
101         uc_ehranges_t ehranges;
102         struct {
103                 uc_variables_t variables;
104                 uc_value_list_t varnames;
105                 uc_offsetinfo_t offsets;
106         } debuginfo;
107 } uc_chunk_t;
108 
109 
110 /* Value type structures */
111 
112 typedef struct uc_weakref {
113         struct uc_weakref *prev;
114         struct uc_weakref *next;
115 } uc_weakref_t;
116 
117 typedef struct uc_function {
118         uc_weakref_t progref;
119         bool arrow, vararg, strict, module;
120         size_t nargs;
121         size_t nupvals;
122         size_t srcidx;
123         size_t srcpos;
124         uc_chunk_t chunk;
125         struct uc_program *program;
126         char name[];
127 } uc_function_t;
128 
129 typedef struct {
130         uc_value_t header;
131         double dbl;
132 } uc_double_t;
133 
134 typedef struct {
135         uc_value_t header;
136         union {
137                 int64_t s64;
138                 uint64_t u64;
139         } i;
140 } uc_integer_t;
141 
142 typedef struct {
143         uc_value_t header;
144         size_t length;
145         char str[];
146 } uc_string_t;
147 
148 typedef struct {
149         uc_value_t header;
150         uc_weakref_t ref;
151         size_t count;
152         uc_value_t *proto;
153         uc_value_t **entries;
154 } uc_array_t;
155 
156 typedef struct {
157         uc_value_t header;
158         uc_weakref_t ref;
159         uc_value_t *proto;
160         struct lh_table *table;
161 } uc_object_t;
162 
163 typedef struct {
164         uc_value_t header;
165         regex_t regexp;
166         bool icase, newline, global;
167         char source[];
168 } uc_regexp_t;
169 
170 typedef struct uc_upval_tref {
171         uc_value_t header;
172         size_t slot;
173         bool closed;
174         uc_value_t *value;
175         struct uc_upval_tref *next;
176 } uc_upvalref_t;
177 
178 typedef struct {
179         uc_value_t header;
180         uc_weakref_t ref;
181         bool is_arrow;
182         uc_function_t *function;
183         uc_upvalref_t **upvals;
184 } uc_closure_t;
185 
186 typedef struct uc_vm uc_vm_t;
187 typedef uc_value_t *(*uc_cfn_ptr_t)(uc_vm_t *, size_t);
188 
189 typedef struct {
190         uc_value_t header;
191         uc_cfn_ptr_t cfn;
192         char name[];
193 } uc_cfunction_t;
194 
195 typedef struct {
196         const char *name;
197         uc_value_t *proto;
198         void (*free)(void *);
199 } uc_resource_type_t;
200 
201 typedef struct {
202         uc_value_t header;
203         uc_resource_type_t *type;
204         void *data;
205 } uc_resource_t;
206 
207 typedef struct {
208         uc_value_t header;
209         uc_weakref_t ref;
210         uc_resource_type_t *type;
211 
212         uint32_t reserved:3;
213         uint32_t persistent:1;
214         uint32_t uvcount:8;
215         uint32_t datasize:20;
216 
217         uint32_t _pad;
218 } uc_resource_ext_t;
219 
220 uc_declare_vector(uc_resource_types_t, uc_resource_type_t *);
221 
222 typedef struct {
223         uc_list_t list;
224         struct lh_table *table;
225         union {
226                 struct lh_entry *pos;
227                 struct {
228                         const void *k;
229                         unsigned long hash;
230                 } kh;
231         } u;
232 } uc_object_iterator_t;
233 
234 
235 /* Program structure definitions */
236 
237 uc_declare_vector(uc_sources_t, uc_source_t *);
238 uc_declare_vector(uc_modexports_t, uc_upvalref_t *);
239 
240 typedef struct uc_program {
241         uc_value_t header;
242         uc_value_list_t constants;
243         uc_weakref_t functions;
244         uc_sources_t sources;
245         uc_modexports_t exports;
246 } uc_program_t;
247 
248 
249 /* Parser definitions */
250 
251 uc_declare_vector(uc_search_path_t, char *);
252 
253 typedef struct {
254         bool lstrip_blocks;
255         bool trim_blocks;
256         bool strict_declarations;
257         bool raw_mode;
258         uc_search_path_t module_search_path;
259         uc_search_path_t force_dynlink_list;
260         bool setup_signal_handlers;
261         bool compile_module;
262 } uc_parse_config_t;
263 
264 extern uc_parse_config_t uc_default_parse_config;
265 
266 void uc_search_path_init(uc_search_path_t *search_path);
267 
268 static inline void
269 uc_search_path_add(uc_search_path_t *search_path, char *path) {
270         uc_vector_push(search_path, xstrdup(path));
271 }
272 
273 static inline void
274 uc_search_path_free(uc_search_path_t *search_path) {
275         while (search_path->count > 0)
276                 free(search_path->entries[--search_path->count]);
277 
278         uc_vector_clear(search_path);
279 }
280 
281 
282 /* TLS data */
283 
284 typedef struct {
285         /* VM owning installed signal handlers */
286         uc_vm_t *signal_handler_vm;
287 
288         /* Reference counter of this thread context for deallocation purposes */
289         size_t refcount;
290 
291         /* Object iteration */
292         uc_list_t object_iterators;
293 } uc_thread_context_t;
294 
295 __hidden uc_thread_context_t *uc_thread_context_get(void);
296 
297 __hidden void uc_thread_context_free(void);
298 
299 /* VM definitions */
300 
301 typedef enum {
302         EXCEPTION_NONE,
303         EXCEPTION_SYNTAX,
304         EXCEPTION_RUNTIME,
305         EXCEPTION_TYPE,
306         EXCEPTION_REFERENCE,
307         EXCEPTION_USER,
308         EXCEPTION_EXIT,
309         EXCEPTION_MAX
310 } uc_exception_type_t;
311 
312 extern const char *exception_type_strings[];
313 
314 typedef struct {
315         uc_exception_type_t type;
316         uc_value_t *stacktrace;
317         char *message;
318 } uc_exception_t;
319 
320 typedef struct {
321         uint8_t *ip;
322         uc_closure_t *closure;
323         uc_cfunction_t *cfunction;
324         size_t stackframe;
325         uc_value_t *ctx;
326         bool mcall, strict;
327 } uc_callframe_t;
328 
329 uc_declare_vector(uc_callframes_t, uc_callframe_t);
330 uc_declare_vector(uc_stack_t, uc_value_t *);
331 
332 typedef struct printbuf uc_stringbuf_t;
333 
334 typedef void (uc_exception_handler_t)(uc_vm_t *, uc_exception_t *);
335 
336 struct uc_vm {
337         uc_stack_t stack;
338         uc_exception_t exception;
339         uc_callframes_t callframes;
340         uc_upvalref_t *open_upvals;
341         uc_parse_config_t *config;
342         uc_value_t *globals;
343         uc_value_t *registry;
344         struct lh_table *sources;
345         uc_weakref_t values;
346         uc_resource_types_t restypes;
347         char _reserved[sizeof(uc_modexports_t)];
348         union {
349                 uint32_t u32;
350                 int32_t s32;
351                 uint16_t u16;
352                 int16_t s16;
353                 uint8_t u8;
354                 int8_t s8;
355         } arg;
356         size_t alloc_refs;
357         uint8_t trace;
358         uint8_t gc_flags;
359         uint16_t gc_interval;
360         uc_stringbuf_t *strbuf;
361         uc_exception_handler_t *exhandler;
362         FILE *output;
363         struct {
364                 uint64_t raised[((UC_SYSTEM_SIGNAL_COUNT + 63) & ~63) / 64];
365                 uc_value_t *handler;
366                 struct sigaction sa;
367                 int sigpipe[2];
368         } signal;
369 };
370 
371 
372 /* Value API */
373 
374 __hidden void ucv_free(uc_value_t *, bool);
375 __hidden void ucv_unref(uc_weakref_t *);
376 __hidden void ucv_ref(uc_weakref_t *, uc_weakref_t *);
377 
378 uc_value_t *ucv_get(uc_value_t *uv);
379 void ucv_put(uc_value_t *);
380 
381 uc_type_t ucv_type(uc_value_t *);
382 const char *ucv_typename(uc_value_t *);
383 
384 uc_value_t *ucv_boolean_new(bool);
385 bool ucv_boolean_get(uc_value_t *);
386 
387 uc_value_t *ucv_string_alloc(char **, size_t);
388 uc_value_t *ucv_string_new(const char *);
389 uc_value_t *ucv_string_new_length(const char *, size_t);
390 size_t ucv_string_length(uc_value_t *);
391 
392 char *_ucv_string_get(uc_value_t **);
393 #define ucv_string_get(uv) _ucv_string_get((uc_value_t **)&uv)
394 
395 uc_stringbuf_t *ucv_stringbuf_new(void);
396 uc_value_t *ucv_stringbuf_finish(uc_stringbuf_t *);
397 
398 void _ucv_stringbuf_append(uc_stringbuf_t *, const char *, size_t);
399 
400 #define _ucv_is_literal(str) ("" str)
401 #define ucv_stringbuf_append(buf, str) _ucv_stringbuf_append(buf, _ucv_is_literal(str), sizeof(str) - 1)
402 #define ucv_stringbuf_addstr(buf, str, len) _ucv_stringbuf_append(buf, str, len)
403 #define ucv_stringbuf_printf(buf, fmt, ...) sprintbuf(buf, fmt, __VA_ARGS__)
404 
405 uc_value_t *ucv_int64_new(int64_t);
406 uc_value_t *ucv_uint64_new(uint64_t);
407 int64_t ucv_int64_get(uc_value_t *);
408 uint64_t ucv_uint64_get(uc_value_t *);
409 
410 uc_value_t *ucv_double_new(double);
411 double ucv_double_get(uc_value_t *);
412 
413 uc_value_t *ucv_array_new(uc_vm_t *);
414 uc_value_t *ucv_array_new_length(uc_vm_t *, size_t);
415 uc_value_t *ucv_array_get(uc_value_t *, size_t);
416 uc_value_t *ucv_array_pop(uc_value_t *);
417 uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *);
418 uc_value_t *ucv_array_shift(uc_value_t *);
419 uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *);
420 void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *));
421 void ucv_array_sort_r(uc_value_t *, int (*)(uc_value_t *, uc_value_t *, void *), void *);
422 bool ucv_array_delete(uc_value_t *, size_t, size_t);
423 bool ucv_array_set(uc_value_t *, size_t, uc_value_t *);
424 size_t ucv_array_length(uc_value_t *);
425 
426 uc_value_t *ucv_object_new(uc_vm_t *);
427 uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *);
428 bool ucv_object_add(uc_value_t *, const char *, uc_value_t *);
429 void ucv_object_sort(uc_value_t *, int (*)(const void *, const void *));
430 void ucv_object_sort_r(uc_value_t *, int (*)(const char *, uc_value_t *, const char *, uc_value_t *, void *), void *);
431 bool ucv_object_delete(uc_value_t *, const char *);
432 size_t ucv_object_length(uc_value_t *);
433 
434 #define ucv_object_foreach(obj, key, val)                                                                                                               \
435         char *key = NULL;                                                                                                                                                       \
436         uc_value_t *val = NULL;                                                                                                                                         \
437         struct lh_entry *entry##key;                                                                                                                            \
438         struct lh_entry *entry_next##key = NULL;                                                                                                        \
439         for (entry##key = (ucv_type(obj) == UC_OBJECT) ? ((uc_object_t *)obj)->table->head : NULL;      \
440              (entry##key ? (key = (char *)lh_entry_k(entry##key),                                                                       \
441                             val = (uc_value_t *)lh_entry_v(entry##key),                                                         \
442                             entry_next##key = entry##key->next, entry##key)                                                     \
443                          : 0);                                                                                                                                          \
444              entry##key = entry_next##key)
445 
446 uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t);
447 
448 uc_value_t *ucv_closure_new(uc_vm_t *, uc_function_t *, bool);
449 
450 uc_resource_type_t *ucv_resource_type_add(uc_vm_t *, const char *, uc_value_t *, void (*)(void *));
451 uc_resource_type_t *ucv_resource_type_lookup(uc_vm_t *, const char *);
452 
453 uc_value_t *ucv_resource_new(uc_resource_type_t *, void *);
454 uc_value_t *ucv_resource_new_ex(uc_vm_t *, uc_resource_type_t *, void **, size_t, size_t);
455 void *ucv_resource_data(uc_value_t *uv, const char *);
456 void **ucv_resource_dataptr(uc_value_t *, const char *);
457 uc_value_t *ucv_resource_value_get(uc_value_t *, size_t);
458 bool ucv_resource_value_set(uc_value_t *, size_t, uc_value_t *);
459 
460 static inline uc_resource_type_t *
461 ucv_resource_type(uc_value_t *uv)
462 {
463                 if (uv->ext_flag) {
464                         uc_resource_ext_t *res = (uc_resource_ext_t *)uv;
465 
466                         return res->type;
467                 }
468                 else {
469                         uc_resource_t *res = (uc_resource_t *)uv;
470 
471                         return res->type;
472                 }
473 }
474 
475 static inline uc_value_t *
476 ucv_resource_create(uc_vm_t *vm, const char *type, void *value)
477 {
478     uc_resource_type_t *t = NULL;
479 
480     if (type && (t = ucv_resource_type_lookup(vm, type)) == NULL)
481         return NULL;
482 
483     return ucv_resource_new(t, value);
484 }
485 
486 static inline uc_value_t *
487 ucv_resource_create_ex(uc_vm_t *vm, const char *type, void **data, size_t uvcount, size_t datasize)
488 {
489     uc_resource_type_t *t = NULL;
490 
491     if (type && (t = ucv_resource_type_lookup(vm, type)) == NULL)
492         return NULL;
493 
494     return ucv_resource_new_ex(vm, t, data, uvcount, datasize);
495 }
496 
497 static inline bool
498 ucv_resource_is_extended(uc_value_t *uv)
499 {
500         return (((uintptr_t)uv & 3) == 0 && uv != NULL &&
501                 uv->ext_flag == true && uv->type == UC_RESOURCE);
502 }
503 
504 static inline bool
505 ucv_resource_is_persistent(uc_value_t *uv)
506 {
507         uc_resource_ext_t *res = (uc_resource_ext_t *)uv;
508 
509         return ucv_resource_is_extended(uv) && res->persistent;
510 }
511 
512 static inline bool
513 ucv_resource_persistent_set(uc_value_t *uv, bool persistent)
514 {
515         uc_resource_ext_t *res = (uc_resource_ext_t *)uv;
516 
517         if (!ucv_resource_is_extended(uv) || res->persistent == persistent)
518                 return false;
519 
520         res->persistent = persistent;
521 
522         return true;
523 }
524 
525 uc_value_t *ucv_regexp_new(const char *, bool, bool, bool, char **);
526 
527 uc_value_t *ucv_upvalref_new(size_t);
528 
529 uc_value_t *ucv_prototype_get(uc_value_t *);
530 bool ucv_prototype_set(uc_value_t *, uc_value_t *);
531 
532 uc_value_t *ucv_property_get(uc_value_t *, const char *);
533 
534 uc_value_t *ucv_from_json(uc_vm_t *, json_object *);
535 json_object *ucv_to_json(uc_value_t *);
536 
537 char *ucv_to_string(uc_vm_t *, uc_value_t *);
538 char *ucv_to_jsonstring_formatted(uc_vm_t *, uc_value_t *, char, size_t);
539 void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_t, char, size_t);
540 
541 #define ucv_to_jsonstring(vm, val) ucv_to_jsonstring_formatted(vm, val, '\1', 0)
542 #define ucv_to_stringbuf(vm, buf, val, json) ucv_to_stringbuf_formatted(vm, buf, val, 0, json ? '\1' : '\0', 0)
543 
544 uc_type_t ucv_cast_number(uc_value_t *, int64_t *, double *);
545 
546 uc_value_t *ucv_to_number(uc_value_t *);
547 
548 static inline double
549 ucv_to_double(uc_value_t *v)
550 {
551         uc_value_t *nv;
552         double d;
553 
554         nv = ucv_to_number(v);
555         d = ucv_double_get(nv);
556         ucv_put(nv);
557 
558         return d;
559 }
560 
561 static inline int64_t
562 ucv_to_integer(uc_value_t *v)
563 {
564         uc_value_t *nv;
565         int64_t n;
566 
567         nv = ucv_to_number(v);
568         n = ucv_int64_get(nv);
569         ucv_put(nv);
570 
571         return n;
572 }
573 
574 static inline uint64_t
575 ucv_to_unsigned(uc_value_t *v)
576 {
577         uc_value_t *nv;
578         uint64_t u;
579 
580         nv = ucv_to_number(v);
581         u = ucv_uint64_get(nv);
582         ucv_put(nv);
583 
584         return u;
585 }
586 
587 static inline bool
588 ucv_is_callable(uc_value_t *uv)
589 {
590         switch (ucv_type(uv)) {
591         case UC_CLOSURE:
592         case UC_CFUNCTION:
593                 return true;
594 
595         default:
596                 return false;
597         }
598 }
599 
600 static inline bool
601 ucv_is_arrowfn(uc_value_t *uv)
602 {
603         uc_closure_t *closure = (uc_closure_t *)uv;
604 
605         return (ucv_type(uv) == UC_CLOSURE && closure->is_arrow);
606 }
607 
608 static inline bool
609 ucv_is_u64(uc_value_t *uv)
610 {
611         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->ext_flag == true &&
612                     uv->type == UC_INTEGER);
613 }
614 
615 static inline bool
616 ucv_is_constant(uc_value_t *uv)
617 {
618         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->ext_flag == true &&
619                 (uv->type == UC_ARRAY || uv->type == UC_OBJECT));
620 }
621 
622 static inline bool
623 ucv_set_constant(uc_value_t *uv, bool constant)
624 {
625         if (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->ext_flag != constant &&
626             (uv->type == UC_ARRAY || uv->type == UC_OBJECT)) {
627                 uv->ext_flag = constant;
628 
629                 return true;
630         }
631 
632         return false;
633 }
634 
635 static inline bool
636 ucv_is_scalar(uc_value_t *uv)
637 {
638         switch (ucv_type(uv)) {
639         case UC_NULL:
640         case UC_BOOLEAN:
641         case UC_DOUBLE:
642         case UC_INTEGER:
643         case UC_STRING:
644                 return true;
645 
646         default:
647                 return false;
648         }
649 }
650 
651 bool ucv_is_equal(uc_value_t *, uc_value_t *);
652 bool ucv_is_truish(uc_value_t *);
653 
654 bool ucv_compare(int, uc_value_t *, uc_value_t *, int *);
655 
656 uc_value_t *ucv_key_get(uc_vm_t *, uc_value_t *, uc_value_t *);
657 uc_value_t *ucv_key_set(uc_vm_t *, uc_value_t *, uc_value_t *, uc_value_t *);
658 bool ucv_key_delete(uc_vm_t *, uc_value_t *, uc_value_t *);
659 
660 
661 static inline bool
662 ucv_is_marked(uc_value_t *uv)
663 {
664         return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->mark == true);
665 }
666 
667 static inline void
668 ucv_set_mark(uc_value_t *uv)
669 {
670         if (((uintptr_t)uv & 3) == 0 && uv != NULL)
671                 uv->mark = true;
672 }
673 
674 static inline void
675 ucv_clear_mark(uc_value_t *uv)
676 {
677         if (((uintptr_t)uv & 3) == 0 && uv != NULL)
678                 uv->mark = false;
679 }
680 
681 void ucv_gc(uc_vm_t *);
682 
683 __hidden void ucv_freeall(uc_vm_t *);
684 
685 #endif /* UCODE_TYPES_H */
686 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt