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