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