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: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 } uc_source_t; 76 77 78 /* Bytecode chunk defintions */ 79 80 typedef struct { 81 size_t from, to, target, slot; 82 } uc_ehrange_t; 83 84 typedef struct { 85 size_t from, to, slot, nameidx; 86 } uc_varrange_t; 87 88 uc_declare_vector(uc_ehranges_t, uc_ehrange_t); 89 uc_declare_vector(uc_variables_t, uc_varrange_t); 90 uc_declare_vector(uc_offsetinfo_t, uint8_t); 91 92 typedef struct { 93 size_t count; 94 uint8_t *entries; 95 uc_ehranges_t ehranges; 96 struct { 97 uc_variables_t variables; 98 uc_value_list_t varnames; 99 uc_offsetinfo_t offsets; 100 } debuginfo; 101 } uc_chunk_t; 102 103 104 /* Value type structures */ 105 106 typedef struct uc_weakref { 107 struct uc_weakref *prev; 108 struct uc_weakref *next; 109 } uc_weakref_t; 110 111 typedef struct uc_function { 112 uc_weakref_t progref; 113 bool arrow, vararg, strict; 114 size_t nargs; 115 size_t nupvals; 116 size_t srcpos; 117 uc_chunk_t chunk; 118 struct uc_program *program; 119 char name[]; 120 } uc_function_t; 121 122 typedef struct { 123 uc_value_t header; 124 double dbl; 125 } uc_double_t; 126 127 typedef struct { 128 uc_value_t header; 129 union { 130 int64_t s64; 131 uint64_t u64; 132 } i; 133 } uc_integer_t; 134 135 typedef struct { 136 uc_value_t header; 137 size_t length; 138 char str[]; 139 } uc_string_t; 140 141 typedef struct { 142 uc_value_t header; 143 uc_weakref_t ref; 144 size_t count; 145 uc_value_t *proto; 146 uc_value_t **entries; 147 } uc_array_t; 148 149 typedef struct { 150 uc_value_t header; 151 uc_weakref_t ref; 152 uc_value_t *proto; 153 struct lh_table *table; 154 } uc_object_t; 155 156 typedef struct { 157 uc_value_t header; 158 regex_t regexp; 159 bool icase, newline, global; 160 char source[]; 161 } uc_regexp_t; 162 163 typedef struct uc_upval_tref { 164 uc_value_t header; 165 size_t slot; 166 bool closed; 167 uc_value_t *value; 168 struct uc_upval_tref *next; 169 } uc_upvalref_t; 170 171 typedef struct { 172 uc_value_t header; 173 uc_weakref_t ref; 174 bool is_arrow; 175 uc_function_t *function; 176 uc_upvalref_t **upvals; 177 } uc_closure_t; 178 179 typedef struct uc_vm uc_vm_t; 180 typedef uc_value_t *(*uc_cfn_ptr_t)(uc_vm_t *, size_t); 181 182 typedef struct { 183 uc_value_t header; 184 uc_cfn_ptr_t cfn; 185 char name[]; 186 } uc_cfunction_t; 187 188 typedef struct { 189 const char *name; 190 uc_value_t *proto; 191 void (*free)(void *); 192 } uc_resource_type_t; 193 194 typedef struct { 195 uc_value_t header; 196 uc_resource_type_t *type; 197 void *data; 198 } uc_resource_t; 199 200 uc_declare_vector(uc_resource_types_t, uc_resource_type_t *); 201 202 203 /* Program structure definitions */ 204 205 typedef struct uc_program { 206 uc_value_t header; 207 uc_value_list_t constants; 208 uc_weakref_t functions; 209 uc_source_t *source; 210 } uc_program_t; 211 212 213 /* Parser definitions */ 214 215 typedef struct { 216 bool lstrip_blocks; 217 bool trim_blocks; 218 bool strict_declarations; 219 bool raw_mode; 220 } uc_parse_config_t; 221 222 223 /* VM definitions */ 224 225 typedef enum { 226 EXCEPTION_NONE, 227 EXCEPTION_SYNTAX, 228 EXCEPTION_RUNTIME, 229 EXCEPTION_TYPE, 230 EXCEPTION_REFERENCE, 231 EXCEPTION_USER, 232 EXCEPTION_EXIT 233 } uc_exception_type_t; 234 235 typedef struct { 236 uc_exception_type_t type; 237 uc_value_t *stacktrace; 238 char *message; 239 } uc_exception_t; 240 241 typedef struct { 242 uint8_t *ip; 243 uc_closure_t *closure; 244 uc_cfunction_t *cfunction; 245 size_t stackframe; 246 uc_value_t *ctx; 247 bool mcall, strict; 248 } uc_callframe_t; 249 250 uc_declare_vector(uc_callframes_t, uc_callframe_t); 251 uc_declare_vector(uc_stack_t, uc_value_t *); 252 253 typedef struct printbuf uc_stringbuf_t; 254 255 typedef void (uc_exception_handler_t)(uc_vm_t *, uc_exception_t *); 256 257 struct uc_vm { 258 uc_stack_t stack; 259 uc_exception_t exception; 260 uc_callframes_t callframes; 261 uc_upvalref_t *open_upvals; 262 uc_parse_config_t *config; 263 uc_value_t *globals; 264 uc_value_t *registry; 265 uc_source_t *sources; 266 uc_weakref_t values; 267 uc_resource_types_t restypes; 268 union { 269 uint32_t u32; 270 int32_t s32; 271 uint16_t u16; 272 int16_t s16; 273 uint8_t u8; 274 int8_t s8; 275 } arg; 276 size_t spread_values; 277 uint8_t trace; 278 uc_stringbuf_t *strbuf; 279 uc_exception_handler_t *exhandler; 280 FILE *output; 281 }; 282 283 284 /* Value API */ 285 286 void ucv_free(uc_value_t *, bool); 287 void ucv_put(uc_value_t *); 288 289 void ucv_unref(uc_weakref_t *); 290 void ucv_ref(uc_weakref_t *, uc_weakref_t *); 291 292 uc_value_t *ucv_get(uc_value_t *uv); 293 294 uc_type_t ucv_type(uc_value_t *); 295 const char *ucv_typename(uc_value_t *); 296 297 uc_value_t *ucv_boolean_new(bool); 298 bool ucv_boolean_get(uc_value_t *); 299 300 uc_value_t *ucv_string_new(const char *); 301 uc_value_t *ucv_string_new_length(const char *, size_t); 302 size_t ucv_string_length(uc_value_t *); 303 304 char *_ucv_string_get(uc_value_t **); 305 #define ucv_string_get(uv) _ucv_string_get((uc_value_t **)&uv) 306 307 uc_stringbuf_t *ucv_stringbuf_new(void); 308 uc_value_t *ucv_stringbuf_finish(uc_stringbuf_t *); 309 310 void _ucv_stringbuf_append(uc_stringbuf_t *, const char *, size_t); 311 312 #define _ucv_is_literal(str) ("" str) 313 #define ucv_stringbuf_append(buf, str) _ucv_stringbuf_append(buf, _ucv_is_literal(str), sizeof(str) - 1) 314 #define ucv_stringbuf_addstr(buf, str, len) _ucv_stringbuf_append(buf, str, len) 315 #define ucv_stringbuf_printf(buf, fmt, ...) sprintbuf(buf, fmt, __VA_ARGS__) 316 317 uc_value_t *ucv_int64_new(int64_t); 318 uc_value_t *ucv_uint64_new(uint64_t); 319 int64_t ucv_int64_get(uc_value_t *); 320 uint64_t ucv_uint64_get(uc_value_t *); 321 322 uc_value_t *ucv_double_new(double); 323 double ucv_double_get(uc_value_t *); 324 325 uc_value_t *ucv_array_new(uc_vm_t *); 326 uc_value_t *ucv_array_new_length(uc_vm_t *, size_t); 327 uc_value_t *ucv_array_get(uc_value_t *, size_t); 328 uc_value_t *ucv_array_pop(uc_value_t *); 329 uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *); 330 uc_value_t *ucv_array_shift(uc_value_t *); 331 uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *); 332 void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *)); 333 bool ucv_array_delete(uc_value_t *, size_t, size_t); 334 bool ucv_array_set(uc_value_t *, size_t, uc_value_t *); 335 size_t ucv_array_length(uc_value_t *); 336 337 uc_value_t *ucv_object_new(uc_vm_t *); 338 uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *); 339 bool ucv_object_add(uc_value_t *, const char *, uc_value_t *); 340 bool ucv_object_delete(uc_value_t *, const char *); 341 size_t ucv_object_length(uc_value_t *); 342 343 #define ucv_object_foreach(obj, key, val) \ 344 char *key = NULL; \ 345 uc_value_t *val = NULL; \ 346 struct lh_entry *entry##key; \ 347 struct lh_entry *entry_next##key = NULL; \ 348 for (entry##key = (ucv_type(obj) == UC_OBJECT) ? ((uc_object_t *)obj)->table->head : NULL; \ 349 (entry##key ? (key = (char *)lh_entry_k(entry##key), \ 350 val = (uc_value_t *)lh_entry_v(entry##key), \ 351 entry_next##key = entry##key->next, entry##key) \ 352 : 0); \ 353 entry##key = entry_next##key) 354 355 uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t); 356 357 uc_value_t *ucv_closure_new(uc_vm_t *, uc_function_t *, bool); 358 359 uc_resource_type_t *ucv_resource_type_add(uc_vm_t *, const char *, uc_value_t *, void (*)(void *)); 360 uc_resource_type_t *ucv_resource_type_lookup(uc_vm_t *, const char *); 361 362 uc_value_t *ucv_resource_new(uc_resource_type_t *, void *); 363 void **ucv_resource_dataptr(uc_value_t *, const char *); 364 365 uc_value_t *ucv_regexp_new(const char *, bool, bool, bool, char **); 366 367 uc_value_t *ucv_upvalref_new(size_t); 368 369 uc_value_t *ucv_prototype_get(uc_value_t *); 370 bool ucv_prototype_set(uc_value_t *, uc_value_t *); 371 372 uc_value_t *ucv_property_get(uc_value_t *, const char *); 373 374 uc_value_t *ucv_from_json(uc_vm_t *, json_object *); 375 json_object *ucv_to_json(uc_value_t *); 376 377 char *ucv_to_string(uc_vm_t *, uc_value_t *); 378 char *ucv_to_jsonstring_formatted(uc_vm_t *, uc_value_t *, char, size_t); 379 void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_t, char, size_t); 380 381 #define ucv_to_jsonstring(vm, val) ucv_to_jsonstring_formatted(vm, val, '\1', 0) 382 #define ucv_to_stringbuf(vm, buf, val, json) ucv_to_stringbuf_formatted(vm, buf, val, 0, json ? '\1' : '\0', 0) 383 384 uc_type_t ucv_cast_number(uc_value_t *, int64_t *, double *); 385 386 uc_value_t *ucv_to_number(uc_value_t *); 387 388 static inline double 389 ucv_to_double(uc_value_t *v) 390 { 391 uc_value_t *nv; 392 double d; 393 394 nv = ucv_to_number(v); 395 d = ucv_double_get(nv); 396 ucv_put(nv); 397 398 return d; 399 } 400 401 static inline int64_t 402 ucv_to_integer(uc_value_t *v) 403 { 404 uc_value_t *nv; 405 int64_t n; 406 407 nv = ucv_to_number(v); 408 n = ucv_int64_get(nv); 409 ucv_put(nv); 410 411 return n; 412 } 413 414 static inline uint64_t 415 ucv_to_unsigned(uc_value_t *v) 416 { 417 uc_value_t *nv; 418 uint64_t u; 419 420 nv = ucv_to_number(v); 421 u = ucv_uint64_get(nv); 422 ucv_put(nv); 423 424 return u; 425 } 426 427 static inline bool 428 ucv_is_callable(uc_value_t *uv) 429 { 430 switch (ucv_type(uv)) { 431 case UC_CLOSURE: 432 case UC_CFUNCTION: 433 return true; 434 435 default: 436 return false; 437 } 438 } 439 440 static inline bool 441 ucv_is_arrowfn(uc_value_t *uv) 442 { 443 uc_closure_t *closure = (uc_closure_t *)uv; 444 445 return (ucv_type(uv) == UC_CLOSURE && closure->is_arrow); 446 } 447 448 static inline bool 449 ucv_is_u64(uc_value_t *uv) 450 { 451 return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64 == true); 452 } 453 454 static inline bool 455 ucv_is_scalar(uc_value_t *uv) 456 { 457 switch (ucv_type(uv)) { 458 case UC_NULL: 459 case UC_BOOLEAN: 460 case UC_DOUBLE: 461 case UC_INTEGER: 462 case UC_STRING: 463 return true; 464 465 default: 466 return false; 467 } 468 } 469 470 bool ucv_is_equal(uc_value_t *, uc_value_t *); 471 bool ucv_is_truish(uc_value_t *); 472 473 bool ucv_compare(int, uc_value_t *, uc_value_t *, int *); 474 475 uc_value_t *ucv_key_get(uc_vm_t *, uc_value_t *, uc_value_t *); 476 uc_value_t *ucv_key_set(uc_vm_t *, uc_value_t *, uc_value_t *, uc_value_t *); 477 bool ucv_key_delete(uc_vm_t *, uc_value_t *, uc_value_t *); 478 479 480 static inline bool 481 ucv_is_marked(uc_value_t *uv) 482 { 483 return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->mark == true); 484 } 485 486 static inline void 487 ucv_set_mark(uc_value_t *uv) 488 { 489 if (((uintptr_t)uv & 3) == 0 && uv != NULL) 490 uv->mark = true; 491 } 492 493 static inline void 494 ucv_clear_mark(uc_value_t *uv) 495 { 496 if (((uintptr_t)uv & 3) == 0 && uv != NULL) 497 uv->mark = false; 498 } 499 500 void ucv_gc(uc_vm_t *); 501 502 void ucv_freeall(uc_vm_t *); 503 504 #endif /* UCODE_TYPES_H */ 505
This page was automatically generated by LXR 0.3.1. • OpenWrt