From e5e7e6277cc757475ad192f70a4b200778e1d8ee Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sat, 10 Jul 2021 14:03:22 +0200 Subject: treewide: move header files into dedicated directory Signed-off-by: Jo-Philipp Wich --- CMakeLists.txt | 4 +- chunk.c | 6 +- chunk.h | 39 ----- compiler.c | 10 +- compiler.h | 117 ------------- include/ucode/chunk.h | 39 +++++ include/ucode/compiler.h | 117 +++++++++++++ include/ucode/lexer.h | 175 +++++++++++++++++++ include/ucode/lib.h | 132 ++++++++++++++ include/ucode/module.h | 53 ++++++ include/ucode/source.h | 36 ++++ include/ucode/types.h | 439 +++++++++++++++++++++++++++++++++++++++++++++++ include/ucode/util.h | 158 +++++++++++++++++ include/ucode/value.h | 60 +++++++ include/ucode/vm.h | 137 +++++++++++++++ lexer.c | 6 +- lexer.h | 175 ------------------- lib.c | 10 +- lib.h | 132 -------------- lib/fs.c | 2 +- lib/math.c | 2 +- lib/ubus.c | 2 +- lib/uci.c | 2 +- main.c | 10 +- module.h | 53 ------ source.c | 2 +- source.h | 36 ---- types.c | 6 +- types.h | 439 ----------------------------------------------- util.h | 158 ----------------- value.c | 8 +- value.h | 60 ------- vm.c | 6 +- vm.h | 137 --------------- 34 files changed, 1385 insertions(+), 1383 deletions(-) delete mode 100644 chunk.h delete mode 100644 compiler.h create mode 100644 include/ucode/chunk.h create mode 100644 include/ucode/compiler.h create mode 100644 include/ucode/lexer.h create mode 100644 include/ucode/lib.h create mode 100644 include/ucode/module.h create mode 100644 include/ucode/source.h create mode 100644 include/ucode/types.h create mode 100644 include/ucode/util.h create mode 100644 include/ucode/value.h create mode 100644 include/ucode/vm.h delete mode 100644 lexer.h delete mode 100644 lib.h delete mode 100644 module.h delete mode 100644 source.h delete mode 100644 types.h delete mode 100644 util.h delete mode 100644 value.h delete mode 100644 vm.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a93b80..83b029e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ IF(CMAKE_C_COMPILER_VERSION VERSION_GREATER 6) ENDIF() ADD_DEFINITIONS(-Wmissing-declarations -Wno-error=unused-variable -Wno-unused-parameter) +INCLUDE_DIRECTORIES(include) + OPTION(FS_SUPPORT "Filesystem plugin support" ON) OPTION(MATH_SUPPORT "Math plugin support" ON) OPTION(UBUS_SUPPORT "Ubus plugin support" ON) @@ -131,5 +133,5 @@ INSTALL(TARGETS ucode RUNTIME DESTINATION bin) INSTALL(TARGETS libucode LIBRARY DESTINATION lib) INSTALL(TARGETS ${LIBRARIES} LIBRARY DESTINATION lib/ucode) -SET(UCODE_HEADERS chunk.h compiler.h lexer.h lib.h module.h source.h types.h util.h value.h vm.h) +FILE(GLOB UCODE_HEADERS "include/ucode/*.h") INSTALL(FILES ${UCODE_HEADERS} DESTINATION include/ucode) diff --git a/chunk.c b/chunk.c index 8b2c447..ab576da 100644 --- a/chunk.c +++ b/chunk.c @@ -16,9 +16,9 @@ #include -#include "chunk.h" -#include "types.h" -#include "util.h" +#include "ucode/chunk.h" +#include "ucode/types.h" +#include "ucode/util.h" #define OFFSETINFO_BITS (sizeof(((uc_offsetinfo_t *)NULL)->entries[0]) * 8) #define OFFSETINFO_BYTE_BITS 3 diff --git a/chunk.h b/chunk.h deleted file mode 100644 index 458af1f..0000000 --- a/chunk.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __CHUNK_H_ -#define __CHUNK_H_ - -#include -#include - -#include "value.h" -#include "util.h" -#include "types.h" - -void uc_chunk_init(uc_chunk_t *chunk); -void uc_chunk_free(uc_chunk_t *chunk); -size_t uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t line); - -ssize_t uc_chunk_add_constant(uc_chunk_t *chunk, uc_value_t *value); -uc_value_t *uc_chunk_get_constant(uc_chunk_t *chunk, size_t idx); -void uc_chunk_pop(uc_chunk_t *chunk); - -size_t uc_chunk_debug_get_srcpos(uc_chunk_t *chunk, size_t off); -void uc_chunk_debug_add_variable(uc_chunk_t *chunk, size_t from, size_t to, size_t slot, bool upval, uc_value_t *name); -uc_value_t *uc_chunk_debug_get_variable(uc_chunk_t *chunk, size_t off, size_t slot, bool upval); - -#endif /* __CHUNK_H_ */ diff --git a/compiler.c b/compiler.c index 9278324..a1d058a 100644 --- a/compiler.c +++ b/compiler.c @@ -16,11 +16,11 @@ #include -#include "compiler.h" -#include "chunk.h" -#include "vm.h" /* I_* */ -#include "source.h" -#include "lib.h" /* format_error_context() */ +#include "ucode/compiler.h" +#include "ucode/chunk.h" +#include "ucode/vm.h" /* I_* */ +#include "ucode/source.h" +#include "ucode/lib.h" /* format_error_context() */ static void uc_compiler_compile_unary(uc_compiler_t *compiler, bool assignable); static void uc_compiler_compile_binary(uc_compiler_t *compiler, bool assignable); diff --git a/compiler.h b/compiler.h deleted file mode 100644 index 19fcf37..0000000 --- a/compiler.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __COMPILER_H_ -#define __COMPILER_H_ - -#include -#include -#include - -#ifdef JSONC - #include -#else - #include -#endif - -#include "source.h" -#include "lexer.h" -#include "types.h" -#include "util.h" - -typedef enum { - P_NONE, - - P_COMMA, /* , */ - - P_ASSIGN, /* = += -= *= /= %= <<= >>= &= ^= |= */ - - P_TERNARY, /* ?: */ - - P_OR, /* || */ - P_AND, /* && */ - P_BOR, /* | */ - P_BXOR, /* ^ */ - P_BAND, /* & */ - - P_EQUAL, /* === !== == != */ - P_COMPARE, /* < <= > >= in */ - - P_SHIFT, /* << >> */ - - P_ADD, /* + - */ - P_MUL, /* * / % */ - - P_UNARY, /* ! ~ +… -… ++… --… */ - - P_INC, /* …++ …-- */ - - P_CALL, /* ….…, …[…], …(…) */ - - P_PRIMARY /* (…) */ -} uc_precedence_t; - -typedef struct uc_patchlist { - struct uc_patchlist *parent; - size_t depth, count, *entries; -} uc_patchlist_t; - -typedef struct { - uc_value_t *name; - ssize_t depth; - size_t from; - bool captured; - bool constant; -} uc_local_t; - -typedef struct { - uc_value_t *name; - size_t index; - bool local; - bool constant; -} uc_upval_t; - -uc_declare_vector(uc_locals_t, uc_local_t); -uc_declare_vector(uc_upvals_t, uc_upval_t); -uc_declare_vector(uc_jmplist_t, size_t); - -typedef struct { - uc_parse_config_t *config; - uc_lexer_t lex; - uc_token_t prev, curr; - bool synchronizing; - uc_stringbuf_t *error; -} uc_parser_t; - -typedef struct uc_compiler { - struct uc_compiler *parent; - uc_locals_t locals; - uc_upvals_t upvals; - uc_patchlist_t *patchlist; - uc_value_t *function; - uc_parser_t *parser; - size_t scope_depth, current_srcpos, last_insn; -} uc_compiler_t; - -typedef struct { - void (*prefix)(uc_compiler_t *, bool); - void (*infix)(uc_compiler_t *, bool); - uc_precedence_t precedence; -} uc_parse_rule_t; - -uc_function_t *uc_compile(uc_parse_config_t *config, uc_source_t *source, char **errp); - -#endif /* __COMPILER_H_ */ diff --git a/include/ucode/chunk.h b/include/ucode/chunk.h new file mode 100644 index 0000000..458af1f --- /dev/null +++ b/include/ucode/chunk.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CHUNK_H_ +#define __CHUNK_H_ + +#include +#include + +#include "value.h" +#include "util.h" +#include "types.h" + +void uc_chunk_init(uc_chunk_t *chunk); +void uc_chunk_free(uc_chunk_t *chunk); +size_t uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t line); + +ssize_t uc_chunk_add_constant(uc_chunk_t *chunk, uc_value_t *value); +uc_value_t *uc_chunk_get_constant(uc_chunk_t *chunk, size_t idx); +void uc_chunk_pop(uc_chunk_t *chunk); + +size_t uc_chunk_debug_get_srcpos(uc_chunk_t *chunk, size_t off); +void uc_chunk_debug_add_variable(uc_chunk_t *chunk, size_t from, size_t to, size_t slot, bool upval, uc_value_t *name); +uc_value_t *uc_chunk_debug_get_variable(uc_chunk_t *chunk, size_t off, size_t slot, bool upval); + +#endif /* __CHUNK_H_ */ diff --git a/include/ucode/compiler.h b/include/ucode/compiler.h new file mode 100644 index 0000000..19fcf37 --- /dev/null +++ b/include/ucode/compiler.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __COMPILER_H_ +#define __COMPILER_H_ + +#include +#include +#include + +#ifdef JSONC + #include +#else + #include +#endif + +#include "source.h" +#include "lexer.h" +#include "types.h" +#include "util.h" + +typedef enum { + P_NONE, + + P_COMMA, /* , */ + + P_ASSIGN, /* = += -= *= /= %= <<= >>= &= ^= |= */ + + P_TERNARY, /* ?: */ + + P_OR, /* || */ + P_AND, /* && */ + P_BOR, /* | */ + P_BXOR, /* ^ */ + P_BAND, /* & */ + + P_EQUAL, /* === !== == != */ + P_COMPARE, /* < <= > >= in */ + + P_SHIFT, /* << >> */ + + P_ADD, /* + - */ + P_MUL, /* * / % */ + + P_UNARY, /* ! ~ +… -… ++… --… */ + + P_INC, /* …++ …-- */ + + P_CALL, /* ….…, …[…], …(…) */ + + P_PRIMARY /* (…) */ +} uc_precedence_t; + +typedef struct uc_patchlist { + struct uc_patchlist *parent; + size_t depth, count, *entries; +} uc_patchlist_t; + +typedef struct { + uc_value_t *name; + ssize_t depth; + size_t from; + bool captured; + bool constant; +} uc_local_t; + +typedef struct { + uc_value_t *name; + size_t index; + bool local; + bool constant; +} uc_upval_t; + +uc_declare_vector(uc_locals_t, uc_local_t); +uc_declare_vector(uc_upvals_t, uc_upval_t); +uc_declare_vector(uc_jmplist_t, size_t); + +typedef struct { + uc_parse_config_t *config; + uc_lexer_t lex; + uc_token_t prev, curr; + bool synchronizing; + uc_stringbuf_t *error; +} uc_parser_t; + +typedef struct uc_compiler { + struct uc_compiler *parent; + uc_locals_t locals; + uc_upvals_t upvals; + uc_patchlist_t *patchlist; + uc_value_t *function; + uc_parser_t *parser; + size_t scope_depth, current_srcpos, last_insn; +} uc_compiler_t; + +typedef struct { + void (*prefix)(uc_compiler_t *, bool); + void (*infix)(uc_compiler_t *, bool); + uc_precedence_t precedence; +} uc_parse_rule_t; + +uc_function_t *uc_compile(uc_parse_config_t *config, uc_source_t *source, char **errp); + +#endif /* __COMPILER_H_ */ diff --git a/include/ucode/lexer.h b/include/ucode/lexer.h new file mode 100644 index 0000000..1b19b60 --- /dev/null +++ b/include/ucode/lexer.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __LEXER_H_ +#define __LEXER_H_ + +#include "source.h" +#include "types.h" + + +typedef enum { + TK_LEXP = 1, + TK_REXP, + TK_LSTM, + TK_RSTM, + TK_IF, + TK_ELSE, + TK_COMMA, + TK_ASSIGN, + TK_ASADD, + TK_ASSUB, + TK_ASMUL, + TK_ASDIV, + TK_ASMOD, + TK_ASLEFT, + TK_ASRIGHT, + TK_ASBAND, + TK_ASBXOR, + TK_ASBOR, + TK_QMARK, + TK_COLON, + TK_OR, + TK_AND, + TK_BOR, + TK_BXOR, + TK_BAND, + TK_EQS, + TK_NES, + TK_EQ, + TK_NE, + TK_LT, + TK_LE, + TK_GT, + TK_GE, + TK_IN, + TK_LSHIFT, + TK_RSHIFT, + TK_ADD, + TK_SUB, + TK_MUL, + TK_DIV, + TK_MOD, + TK_NOT, + TK_COMPL, + TK_INC, + TK_DEC, + TK_DOT, + TK_LBRACK, + TK_RBRACK, + TK_LPAREN, + TK_RPAREN, + TK_TEXT, + TK_LBRACE, + TK_RBRACE, + TK_SCOL, + TK_ENDIF, + TK_ELIF, + TK_WHILE, + TK_ENDWHILE, + TK_FOR, + TK_ENDFOR, + TK_FUNC, + TK_LABEL, + TK_ENDFUNC, + TK_TRY, + TK_CATCH, + TK_SWITCH, + TK_CASE, + TK_DEFAULT, + TK_ELLIP, + TK_RETURN, + TK_BREAK, + TK_CONTINUE, + TK_LOCAL, + TK_ARROW, + TK_TRUE, + TK_FALSE, + TK_NUMBER, + TK_DOUBLE, + TK_STRING, + TK_REGEXP, + TK_NULL, + TK_THIS, + TK_DELETE, + TK_CONST, + + TK_EOF, + TK_ERROR +} uc_tokentype_t; + +typedef enum { + UC_LEX_IDENTIFY_BLOCK, + UC_LEX_BLOCK_COMMENT_START, + UC_LEX_BLOCK_EXPRESSION_START, + UC_LEX_BLOCK_EXPRESSION_EMIT_TAG, + UC_LEX_BLOCK_STATEMENT_START, + UC_LEX_BLOCK_COMMENT, + UC_LEX_IDENTIFY_TOKEN, + UC_LEX_PARSE_TOKEN, + UC_LEX_EOF +} uc_lex_state_t; + +typedef struct { + uc_tokentype_t type; + uc_value_t *uv; + size_t pos; +} uc_token_t; + +typedef struct { + uc_lex_state_t state; + uc_parse_config_t *config; + uc_source_t *source; + uint8_t eof:1; + uint8_t is_escape:1; + uint8_t no_regexp:1; + uint8_t no_keyword:1; + size_t buflen; + char *buf, *bufstart, *bufend; + size_t lookbehindlen; + char *lookbehind; + const void *tok; + uc_token_t curr; + char esc[5]; + uint8_t esclen; + int lead_surrogate; + size_t lastoff; + enum { + UNSPEC, + PLUS, + MINUS, + NEWLINE + } modifier; + enum { + NONE, + EXPRESSION = '{', + STATEMENTS = '%', + COMMENT = '#' + } block; +} uc_lexer_t; + + +void uc_lexer_init(uc_lexer_t *lex, uc_parse_config_t *config, uc_source_t *source); +void uc_lexer_free(uc_lexer_t *lex); + +uc_token_t *uc_lexer_next_token(uc_lexer_t *lex); + +bool utf8enc(char **out, int *rem, int code); + +const char * +uc_get_tokenname(unsigned type); + +#endif /* __LEXER_H_ */ diff --git a/include/ucode/lib.h b/include/ucode/lib.h new file mode 100644 index 0000000..7eeae9f --- /dev/null +++ b/include/ucode/lib.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __LIB_H_ +#define __LIB_H_ + +#include "vm.h" +#include "lexer.h" + +typedef struct { + const char *name; + uc_cfn_ptr_t func; +} uc_cfunction_list_t; + +extern const uc_cfunction_list_t uc_stdlib_functions[]; + +void uc_load_stdlib(uc_value_t *scope); + +bool format_source_context(uc_stringbuf_t *buf, uc_source_t *src, size_t off, bool compact); +bool format_error_context(uc_stringbuf_t *buf, uc_source_t *src, uc_value_t *stacktrace, size_t off); + + +/* vm helper */ + +static inline void * +_uc_get_self(uc_vm_t *vm, const char *expected_type) +{ + return ucv_ressource_dataptr(vm->callframes.entries[vm->callframes.count - 1].ctx, expected_type); +} + +#define uc_get_self(...) _uc_get_self(vm, __VA_ARGS__) + +static inline uc_value_t * +_uc_get_arg(uc_vm_t *vm, size_t nargs, size_t n) +{ + if (n >= nargs) + return NULL; + + return uc_vm_stack_peek(vm, nargs - n - 1); +} + +#define uc_get_arg(...) _uc_get_arg(vm, nargs, __VA_ARGS__) + +#define uc_call(nargs) uc_vm_call(vm, false, nargs) +#define uc_push_val(val) uc_vm_stack_push(vm, val) +#define uc_pop_val() uc_vm_stack_pop(vm) + + +/* value helper */ + +static inline uc_value_t * +uc_alloc_ressource(uc_ressource_type_t *type, void *data) +{ + return ucv_ressource_new(type, data); +} + +static inline uc_type_t +uc_to_number(uc_value_t *v, int64_t *n, double *d) +{ + return uc_cast_number(v, n, d); +} + +static inline double +uc_to_double(uc_value_t *v) +{ + int64_t n; + double d; + + return (uc_cast_number(v, &n, &d) == UC_DOUBLE) ? d : (double)n; +} + +static inline int64_t +uc_to_int64(uc_value_t *v) +{ + int64_t n; + double d; + + return (uc_cast_number(v, &n, &d) == UC_DOUBLE) ? (int64_t)d : n; +} + + +/* ressource type helper */ + +static inline uc_ressource_type_t * +_uc_declare_type(uc_vm_t *vm, const char *name, const uc_cfunction_list_t *list, size_t len, void (*freefn)(void *)) +{ + uc_value_t *proto = ucv_object_new(NULL); + + while (len-- > 0) + ucv_object_add(proto, list[len].name, + ucv_cfunction_new(list[len].name, list[len].func)); + + return ucv_ressource_type_add(vm, name, proto, freefn); +} + +#define uc_declare_type(vm, name, functions, freefn) \ + _uc_declare_type(vm, name, functions, ARRAY_SIZE(functions), freefn) + + +/* function helper */ + +#define uc_add_function(object, name, function) \ + ucv_object_add(object, name, ucv_cfunction_new(name, function)) + +static inline bool +_uc_add_functions(uc_value_t *object, const uc_cfunction_list_t *list, size_t len) +{ + bool rv = true; + + while (len-- > 0) + rv &= uc_add_function(object, list[len].name, list[len].func); + + return rv; +} + +#define uc_add_functions(object, functions) \ + _uc_add_functions(object, functions, ARRAY_SIZE(functions)) + +#endif /* __LIB_H_ */ diff --git a/include/ucode/module.h b/include/ucode/module.h new file mode 100644 index 0000000..43d9d51 --- /dev/null +++ b/include/ucode/module.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __MODULE_H_ +#define __MODULE_H_ + +#include "lib.h" +#include "vm.h" + +#define register_functions(scope, functions) \ + if (scope) \ + for (int i = 0; i < ARRAY_SIZE(functions); i++) \ + json_object_object_add(scope->header.jso, functions[i].name, \ + ops->value.cfunc(functions[i].name, functions[i].func)) + +#define alloc_prototype(functions) ({ \ + uc_prototype *__proto = uc_object_as_prototype(ops->value.proto(NULL)); \ + register_functions(__proto, functions); \ + __proto; \ +}) + +#define declare_type(name, proto, freefn) \ + ucv_ressource_type_add(name, proto, freefn) + +#define alloc_ressource(data, type) \ + ucv_ressource_new(ucv_object_new(NULL), type, data) + +#define register_ressource(scope, key, res) \ + json_object_object_add((scope)->header.jso, key, (res)->header.jso) + +void uc_module_init(uc_vm_t *vm, uc_value_t *scope) __attribute__((weak)); + +void uc_module_entry(uc_vm_t *vm, uc_value_t *scope); +void uc_module_entry(uc_vm_t *vm, uc_value_t *scope) +{ + if (uc_module_init) + uc_module_init(vm, scope); +} + +#endif /* __MODULE_H_ */ diff --git a/include/ucode/source.h b/include/ucode/source.h new file mode 100644 index 0000000..3de7c93 --- /dev/null +++ b/include/ucode/source.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __SOURCE_H_ +#define __SOURCE_H_ + +#include +#include +#include + +#include "util.h" +#include "types.h" + + +uc_source_t *uc_source_new_file(const char *path); +uc_source_t *uc_source_new_buffer(const char *name, char *buf, size_t len); + +size_t uc_source_get_line(uc_source_t *source, size_t *offset); + +uc_source_t *uc_source_get(uc_source_t *source); +void uc_source_put(uc_source_t *source); + +#endif /* __SOURCE_H_ */ diff --git a/include/ucode/types.h b/include/ucode/types.h new file mode 100644 index 0000000..e2cb15d --- /dev/null +++ b/include/ucode/types.h @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __TYPES_H_ +#define __TYPES_H_ + +#include +#include +#include +#include + +#include "util.h" + + +/* Value types and generic value header */ + +typedef enum uc_type { + UC_NULL, + UC_INTEGER, + UC_BOOLEAN, + UC_STRING, + UC_DOUBLE, + UC_ARRAY, + UC_OBJECT, + UC_REGEXP, + UC_FUNCTION, + UC_CFUNCTION, + UC_CLOSURE, + UC_UPVALUE, + UC_RESSOURCE +} uc_type_t; + +typedef struct uc_value { + uint32_t type:4; + uint32_t mark:1; + uint32_t u64:1; + uint32_t refcount:26; +} uc_value_t; + + +/* Constant list defintions */ + +typedef struct { + size_t isize; + size_t dsize; + uint64_t *index; + char *data; +} uc_value_list_t; + + +/* Source buffer defintions */ + +uc_declare_vector(uc_lineinfo_t, uint8_t); + +typedef struct { + char *filename, *buffer; + FILE *fp; + size_t usecount, off; + uc_lineinfo_t lineinfo; +} uc_source_t; + + +/* Bytecode chunk defintions */ + +typedef struct { + size_t from, to, target, slot; +} uc_ehrange_t; + +typedef struct { + size_t from, to, slot, nameidx; +} uc_varrange_t; + +uc_declare_vector(uc_ehranges_t, uc_ehrange_t); +uc_declare_vector(uc_variables_t, uc_varrange_t); +uc_declare_vector(uc_offsetinfo_t, uint8_t); + +typedef struct { + size_t count; + uint8_t *entries; + uc_value_list_t constants; + uc_ehranges_t ehranges; + struct { + uc_variables_t variables; + uc_value_list_t varnames; + uc_offsetinfo_t offsets; + } debuginfo; +} uc_chunk_t; + + +/* Value type structures */ + +typedef struct uc_weakref { + struct uc_weakref *prev; + struct uc_weakref *next; +} uc_weakref_t; + +typedef struct { + uc_value_t header; + double dbl; +} uc_double_t; + +typedef struct { + uc_value_t header; + union { + int64_t s64; + uint64_t u64; + } i; +} uc_integer_t; + +typedef struct { + uc_value_t header; + size_t length; + char str[]; +} uc_string_t; + +typedef struct { + uc_value_t header; + uc_weakref_t ref; + size_t count; + uc_value_t *proto; + uc_value_t **entries; +} uc_array_t; + +typedef struct { + uc_value_t header; + uc_weakref_t ref; + uc_value_t *proto; + struct lh_table *table; +} uc_object_t; + +typedef struct { + uc_value_t header; + regex_t regexp; + bool icase, newline, global; + char source[]; +} uc_regexp_t; + +typedef struct { + uc_value_t header; + bool arrow, vararg, strict; + size_t nargs; + size_t nupvals; + size_t srcpos; + uc_chunk_t chunk; + uc_source_t *source; + char name[]; +} uc_function_t; + +typedef struct uc_upval_tref { + uc_value_t header; + size_t slot; + bool closed; + uc_value_t *value; + struct uc_upval_tref *next; +} uc_upval_tref_t; + +typedef struct { + uc_value_t header; + uc_weakref_t ref; + bool is_arrow; + uc_function_t *function; + uc_upval_tref_t **upvals; +} uc_closure_t; + +typedef struct uc_vm uc_vm_t; +typedef uc_value_t *(*uc_cfn_ptr_t)(uc_vm_t *, size_t); + +typedef struct { + uc_value_t header; + uc_cfn_ptr_t cfn; + char name[]; +} uc_cfunction_t; + +typedef struct { + const char *name; + uc_value_t *proto; + void (*free)(void *); +} uc_ressource_type_t; + +typedef struct { + uc_value_t header; + uc_ressource_type_t *type; + void *data; +} uc_ressource_t; + +uc_declare_vector(uc_ressource_types_t, uc_ressource_type_t *); + + +/* Parser definitions */ + +typedef struct { + bool lstrip_blocks; + bool trim_blocks; + bool strict_declarations; + bool raw_mode; +} uc_parse_config_t; + + +/* VM definitions */ + +typedef enum { + EXCEPTION_NONE, + EXCEPTION_SYNTAX, + EXCEPTION_RUNTIME, + EXCEPTION_TYPE, + EXCEPTION_REFERENCE, + EXCEPTION_USER, + EXCEPTION_EXIT +} uc_exception_type_t; + +typedef struct { + uc_exception_type_t type; + uc_value_t *stacktrace; + char *message; +} uc_exception_t; + +typedef struct { + uint8_t *ip; + uc_closure_t *closure; + uc_cfunction_t *cfunction; + size_t stackframe; + uc_value_t *ctx; + bool mcall, strict; +} uc_callframe_t; + +uc_declare_vector(uc_callframes_t, uc_callframe_t); +uc_declare_vector(uc_stack_t, uc_value_t *); + +typedef struct printbuf uc_stringbuf_t; + +typedef void (uc_exception_handler_t)(uc_vm_t *, uc_exception_t *); + +struct uc_vm { + uc_stack_t stack; + uc_exception_t exception; + uc_callframes_t callframes; + uc_upval_tref_t *open_upvals; + uc_parse_config_t *config; + uc_value_t *globals; + uc_source_t *sources; + uc_weakref_t values; + uc_ressource_types_t restypes; + union { + uint32_t u32; + int32_t s32; + uint16_t u16; + int16_t s16; + uint8_t u8; + int8_t s8; + } arg; + size_t spread_values; + uint8_t trace; + uc_stringbuf_t *strbuf; + uc_exception_handler_t *exhandler; + FILE *output; +}; + + +/* Value API */ + +void ucv_free(uc_value_t *, bool); +void ucv_put(uc_value_t *); + +uc_value_t *ucv_get(uc_value_t *uv); + +uc_type_t ucv_type(uc_value_t *); +const char *ucv_typename(uc_value_t *); + +uc_value_t *ucv_boolean_new(bool); +bool ucv_boolean_get(uc_value_t *); + +uc_value_t *ucv_string_new(const char *); +uc_value_t *ucv_string_new_length(const char *, size_t); +size_t ucv_string_length(uc_value_t *); + +char *_ucv_string_get(uc_value_t **); +#define ucv_string_get(uv) _ucv_string_get((uc_value_t **)&uv) + +uc_stringbuf_t *ucv_stringbuf_new(void); +uc_value_t *ucv_stringbuf_finish(uc_stringbuf_t *); + +void _ucv_stringbuf_append(uc_stringbuf_t *, const char *, size_t); + +#define _ucv_is_literal(str) ("" str) +#define ucv_stringbuf_append(buf, str) _ucv_stringbuf_append(buf, _ucv_is_literal(str), sizeof(str) - 1) +#define ucv_stringbuf_addstr(buf, str, len) _ucv_stringbuf_append(buf, str, len) +#define ucv_stringbuf_printf(buf, fmt, ...) sprintbuf(buf, fmt, __VA_ARGS__) + +uc_value_t *ucv_int64_new(int64_t); +uc_value_t *ucv_uint64_new(uint64_t); +int64_t ucv_int64_get(uc_value_t *); +uint64_t ucv_uint64_get(uc_value_t *); + +uc_value_t *ucv_double_new(double); +double ucv_double_get(uc_value_t *); + +uc_value_t *ucv_array_new(uc_vm_t *); +uc_value_t *ucv_array_new_length(uc_vm_t *, size_t); +uc_value_t *ucv_array_get(uc_value_t *, size_t); +uc_value_t *ucv_array_pop(uc_value_t *); +uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *); +uc_value_t *ucv_array_shift(uc_value_t *); +uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *); +void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *)); +bool ucv_array_delete(uc_value_t *, size_t, size_t); +bool ucv_array_set(uc_value_t *, size_t, uc_value_t *); +size_t ucv_array_length(uc_value_t *); + +uc_value_t *ucv_object_new(uc_vm_t *); +uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *); +bool ucv_object_add(uc_value_t *, const char *, uc_value_t *); +bool ucv_object_delete(uc_value_t *, const char *); +size_t ucv_object_length(uc_value_t *); + +#define ucv_object_foreach(obj, key, val) \ + char *key = NULL; \ + uc_value_t *val = NULL; \ + struct lh_entry *entry##key; \ + struct lh_entry *entry_next##key = NULL; \ + for (entry##key = (ucv_type(obj) == UC_OBJECT) ? ((uc_object_t *)obj)->table->head : NULL; \ + (entry##key ? (key = (char *)lh_entry_k(entry##key), \ + val = (uc_value_t *)lh_entry_v(entry##key), \ + entry_next##key = entry##key->next, entry##key) \ + : 0); \ + entry##key = entry_next##key) + +uc_value_t *ucv_function_new(const char *, size_t, uc_source_t *); +size_t ucv_function_srcpos(uc_value_t *, size_t); + +uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t); + +uc_value_t *ucv_closure_new(uc_vm_t *, uc_function_t *, bool); + +uc_ressource_type_t *ucv_ressource_type_add(uc_vm_t *, const char *, uc_value_t *, void (*)(void *)); +uc_ressource_type_t *ucv_ressource_type_lookup(uc_vm_t *, const char *); + +uc_value_t *ucv_ressource_new(uc_ressource_type_t *, void *); +void **ucv_ressource_dataptr(uc_value_t *, const char *); + +uc_value_t *ucv_regexp_new(const char *, bool, bool, bool, char **); + +uc_value_t *ucv_upvalref_new(size_t); + +uc_value_t *ucv_prototype_get(uc_value_t *); +bool ucv_prototype_set(uc_value_t *, uc_value_t *); + +uc_value_t *ucv_property_get(uc_value_t *, const char *); + +uc_value_t *ucv_from_json(uc_vm_t *, json_object *); +json_object *ucv_to_json(uc_value_t *); + +char *ucv_to_string(uc_vm_t *, uc_value_t *); +char *ucv_to_jsonstring_formatted(uc_vm_t *, uc_value_t *, char, size_t); +void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_t, char, size_t); + +#define ucv_to_jsonstring(vm, val) ucv_to_jsonstring_formatted(vm, val, '\1', 0) +#define ucv_to_stringbuf(vm, buf, val, json) ucv_to_stringbuf_formatted(vm, buf, val, 0, json ? '\1' : '\0', 0) + +static inline bool +ucv_is_callable(uc_value_t *uv) +{ + switch (ucv_type(uv)) { + case UC_CLOSURE: + case UC_CFUNCTION: + return true; + + default: + return false; + } +} + +static inline bool +ucv_is_arrowfn(uc_value_t *uv) +{ + uc_closure_t *closure = (uc_closure_t *)uv; + + return (ucv_type(uv) == UC_CLOSURE && closure->is_arrow); +} + +static inline bool +ucv_is_u64(uc_value_t *uv) +{ + return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64 == true); +} + +static inline bool +ucv_is_scalar(uc_value_t *uv) +{ + switch (ucv_type(uv)) { + case UC_NULL: + case UC_BOOLEAN: + case UC_DOUBLE: + case UC_INTEGER: + case UC_STRING: + return true; + + default: + return false; + } +} + +static inline bool +ucv_is_marked(uc_value_t *uv) +{ + return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->mark == true); +} + +static inline void +ucv_set_mark(uc_value_t *uv) +{ + if (((uintptr_t)uv & 3) == 0 && uv != NULL) + uv->mark = true; +} + +static inline void +ucv_clear_mark(uc_value_t *uv) +{ + if (((uintptr_t)uv & 3) == 0 && uv != NULL) + uv->mark = false; +} + +bool ucv_equal(uc_value_t *, uc_value_t *); + +void ucv_gc(uc_vm_t *, bool); + +#endif /* __TYPES_H_ */ diff --git a/include/ucode/util.h b/include/ucode/util.h new file mode 100644 index 0000000..858a3fd --- /dev/null +++ b/include/ucode/util.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __UTIL_H_ +#define __UTIL_H_ + +#include +#include +#include +#include +#include /* va_start(), va_end(), va_list */ +#include /* strdup() */ +#include + + +/* alignment & array size */ + +#ifndef ALIGN +#define ALIGN(x) (((x) + sizeof(size_t) - 1) & -sizeof(size_t)) +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#endif + + +/* vector macros */ + +#define UC_VECTOR_CHUNK_SIZE 8 + +#define uc_declare_vector(name, type) \ + typedef struct { \ + size_t count; \ + type *entries; \ + } name + +#define uc_vector_grow(vec) \ + do { \ + if (((vec)->count % UC_VECTOR_CHUNK_SIZE) == 0) { \ + (vec)->entries = xrealloc((vec)->entries, sizeof((vec)->entries[0]) * ((vec)->count + UC_VECTOR_CHUNK_SIZE)); \ + memset(&(vec)->entries[(vec)->count], 0, sizeof((vec)->entries[0]) * UC_VECTOR_CHUNK_SIZE); \ + } \ + } while(0) + +#define uc_vector_clear(vec) \ + do { \ + free((vec)->entries); \ + (vec)->entries = NULL; \ + (vec)->count = 0; \ + } while(0) + +#define uc_vector_first(vec) \ + (&((vec)->entries[0])) + +#define uc_vector_last(vec) \ + (&((vec)->entries[(vec)->count - 1])) + + +/* "failsafe" utility functions */ + +static inline void *xalloc(size_t size) { + void *ptr = calloc(1, size); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline void *xrealloc(void *ptr, size_t size) { + ptr = realloc(ptr, size); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline char *xstrdup(const char *s) { + char *ptr = strdup(s); + + if (!ptr) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return ptr; +} + +static inline struct json_tokener *xjs_new_tokener(void) { + struct json_tokener *tok = json_tokener_new(); + + if (!tok) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return tok; +} + +__attribute__((format(printf, 2, 0))) +static inline int xasprintf(char **strp, const char *fmt, ...) { + va_list ap; + int len; + + va_start(ap, fmt); + len = vasprintf(strp, fmt, ap); + va_end(ap); + + if (len == -1) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return len; +} + +__attribute__((format(printf, 2, 0))) +static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { + int len = vasprintf(strp, fmt, ap); + + if (len == -1) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return len; +} + +static inline struct printbuf *xprintbuf_new(void) { + struct printbuf *pb = printbuf_new(); + + if (!pb) { + fprintf(stderr, "Out of memory\n"); + abort(); + } + + return pb; +} + +#endif /* __UTIL_H_ */ diff --git a/include/ucode/value.h b/include/ucode/value.h new file mode 100644 index 0000000..04d37a9 --- /dev/null +++ b/include/ucode/value.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __VALUE_H_ +#define __VALUE_H_ + +#include +#include +#include + +#ifdef JSONC + #include +#else + #include +#endif + +#include + +#include "types.h" + +typedef enum { + TAG_INVAL = 0, + TAG_NUM = 1, + TAG_LNUM = 2, + TAG_DBL = 3, + TAG_STR = 4, + TAG_LSTR = 5, + TAG_PTR = 6 +} uc_value_type_t; + +bool uc_cmp(int how, uc_value_t *v1, uc_value_t *v2); +bool uc_val_is_truish(uc_value_t *val); + +uc_type_t uc_cast_number(uc_value_t *v, int64_t *n, double *d); + +uc_value_t *uc_getval(uc_vm_t *, uc_value_t *scope, uc_value_t *key); +uc_value_t *uc_setval(uc_vm_t *, uc_value_t *scope, uc_value_t *key, uc_value_t *val); +bool uc_delval(uc_vm_t *, uc_value_t *scope, uc_value_t *key); + +void uc_vallist_init(uc_value_list_t *list); +void uc_vallist_free(uc_value_list_t *list); + +ssize_t uc_vallist_add(uc_value_list_t *list, uc_value_t *value); +uc_value_type_t uc_vallist_type(uc_value_list_t *list, size_t idx); +uc_value_t *uc_vallist_get(uc_value_list_t *list, size_t idx); + +#endif /* __VALUE_H_ */ diff --git a/include/ucode/vm.h b/include/ucode/vm.h new file mode 100644 index 0000000..553cf61 --- /dev/null +++ b/include/ucode/vm.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2020-2021 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __VM_H_ +#define __VM_H_ + +#include +#include + +#include "chunk.h" +#include "util.h" +#include "lexer.h" +#include "types.h" + +#define __insns \ +__insn(NOOP) \ +__insn(LOAD) \ +__insn(LOAD8) \ +__insn(LOAD16) \ +__insn(LOAD32) \ +__insn(LTHIS) \ +__insn(LREXP) \ +__insn(LNULL) \ +__insn(LTRUE) \ +__insn(LFALSE) \ +__insn(LLOC) \ +__insn(LUPV) \ +__insn(LVAR) \ +__insn(LVAL) \ +__insn(CLFN) \ +__insn(ARFN) \ +__insn(SLOC) \ +__insn(SUPV) \ +__insn(SVAR) \ +__insn(SVAL) \ +__insn(ULOC) \ +__insn(UUPV) \ +__insn(UVAR) \ +__insn(UVAL) \ +__insn(NARR) \ +__insn(PARR) \ +__insn(MARR) \ +__insn(NOBJ) \ +__insn(SOBJ) \ +__insn(MOBJ) \ +__insn(BOR) \ +__insn(BXOR) \ +__insn(BAND) \ +__insn(EQS) \ +__insn(NES) \ +__insn(EQ) \ +__insn(NE) \ +__insn(LT) \ +__insn(LE) \ +__insn(GT) \ +__insn(GE) \ +__insn(IN) \ +__insn(LSHIFT) \ +__insn(RSHIFT) \ +__insn(ADD) \ +__insn(SUB) \ +__insn(MUL) \ +__insn(DIV) \ +__insn(MOD) \ +__insn(NOT) \ +__insn(COMPL) \ +__insn(PLUS) \ +__insn(MINUS) \ +__insn(JMP) \ +__insn(JMPZ) \ +__insn(COPY) \ +__insn(POP) \ +__insn(CUPV) \ +__insn(RETURN) \ +__insn(CALL) \ +__insn(MCALL) \ +__insn(PRINT) \ +__insn(NEXTK) \ +__insn(NEXTKV) \ +__insn(DELETE) + + +#undef __insn +#define __insn(_name) I_##_name, + +typedef enum { + __insns + __I_MAX +} uc_vm_insn_t; + +typedef enum { + STATUS_OK, + STATUS_EXIT, + ERROR_COMPILE, + ERROR_RUNTIME +} uc_vm_status_t; + +extern uint32_t insns[__I_MAX]; + +void uc_vm_init(uc_vm_t *vm, uc_parse_config_t *config); +void uc_vm_free(uc_vm_t *vm); + +uc_value_t *uc_vm_scope_get(uc_vm_t *vm); +void uc_vm_scope_set(uc_vm_t *vm, uc_value_t *ctx); + +void uc_vm_stack_push(uc_vm_t *vm, uc_value_t *value); +uc_value_t *uc_vm_stack_pop(uc_vm_t *vm); +uc_value_t *uc_vm_stack_peek(uc_vm_t *vm, size_t offset); + +uc_exception_handler_t *uc_vm_exception_handler_get(uc_vm_t *vm); +void uc_vm_exception_handler_set(uc_vm_t *vm, uc_exception_handler_t *exhandler); + +uint32_t uc_vm_trace_get(uc_vm_t *vm); +void uc_vm_trace_set(uc_vm_t *vm, uint32_t level); + +uc_exception_type_t uc_vm_call(uc_vm_t *vm, bool mcall, size_t nargs); + +void __attribute__((format(printf, 3, 0))) +uc_vm_raise_exception(uc_vm_t *vm, uc_exception_type_t type, const char *fmt, ...); + +uc_vm_status_t uc_vm_execute(uc_vm_t *vm, uc_function_t *fn, uc_value_t **retval); +uc_value_t *uc_vm_invoke(uc_vm_t *vm, const char *fname, size_t nargs, ...); + +#endif /* __VM_H_ */ diff --git a/lexer.c b/lexer.c index 8e6378a..07b3cb5 100644 --- a/lexer.c +++ b/lexer.c @@ -25,9 +25,9 @@ #include #include -#include "vm.h" -#include "lib.h" -#include "lexer.h" +#include "ucode/vm.h" +#include "ucode/lib.h" +#include "ucode/lexer.h" #define UC_LEX_CONTINUE_PARSING (void *)1 diff --git a/lexer.h b/lexer.h deleted file mode 100644 index 1b19b60..0000000 --- a/lexer.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __LEXER_H_ -#define __LEXER_H_ - -#include "source.h" -#include "types.h" - - -typedef enum { - TK_LEXP = 1, - TK_REXP, - TK_LSTM, - TK_RSTM, - TK_IF, - TK_ELSE, - TK_COMMA, - TK_ASSIGN, - TK_ASADD, - TK_ASSUB, - TK_ASMUL, - TK_ASDIV, - TK_ASMOD, - TK_ASLEFT, - TK_ASRIGHT, - TK_ASBAND, - TK_ASBXOR, - TK_ASBOR, - TK_QMARK, - TK_COLON, - TK_OR, - TK_AND, - TK_BOR, - TK_BXOR, - TK_BAND, - TK_EQS, - TK_NES, - TK_EQ, - TK_NE, - TK_LT, - TK_LE, - TK_GT, - TK_GE, - TK_IN, - TK_LSHIFT, - TK_RSHIFT, - TK_ADD, - TK_SUB, - TK_MUL, - TK_DIV, - TK_MOD, - TK_NOT, - TK_COMPL, - TK_INC, - TK_DEC, - TK_DOT, - TK_LBRACK, - TK_RBRACK, - TK_LPAREN, - TK_RPAREN, - TK_TEXT, - TK_LBRACE, - TK_RBRACE, - TK_SCOL, - TK_ENDIF, - TK_ELIF, - TK_WHILE, - TK_ENDWHILE, - TK_FOR, - TK_ENDFOR, - TK_FUNC, - TK_LABEL, - TK_ENDFUNC, - TK_TRY, - TK_CATCH, - TK_SWITCH, - TK_CASE, - TK_DEFAULT, - TK_ELLIP, - TK_RETURN, - TK_BREAK, - TK_CONTINUE, - TK_LOCAL, - TK_ARROW, - TK_TRUE, - TK_FALSE, - TK_NUMBER, - TK_DOUBLE, - TK_STRING, - TK_REGEXP, - TK_NULL, - TK_THIS, - TK_DELETE, - TK_CONST, - - TK_EOF, - TK_ERROR -} uc_tokentype_t; - -typedef enum { - UC_LEX_IDENTIFY_BLOCK, - UC_LEX_BLOCK_COMMENT_START, - UC_LEX_BLOCK_EXPRESSION_START, - UC_LEX_BLOCK_EXPRESSION_EMIT_TAG, - UC_LEX_BLOCK_STATEMENT_START, - UC_LEX_BLOCK_COMMENT, - UC_LEX_IDENTIFY_TOKEN, - UC_LEX_PARSE_TOKEN, - UC_LEX_EOF -} uc_lex_state_t; - -typedef struct { - uc_tokentype_t type; - uc_value_t *uv; - size_t pos; -} uc_token_t; - -typedef struct { - uc_lex_state_t state; - uc_parse_config_t *config; - uc_source_t *source; - uint8_t eof:1; - uint8_t is_escape:1; - uint8_t no_regexp:1; - uint8_t no_keyword:1; - size_t buflen; - char *buf, *bufstart, *bufend; - size_t lookbehindlen; - char *lookbehind; - const void *tok; - uc_token_t curr; - char esc[5]; - uint8_t esclen; - int lead_surrogate; - size_t lastoff; - enum { - UNSPEC, - PLUS, - MINUS, - NEWLINE - } modifier; - enum { - NONE, - EXPRESSION = '{', - STATEMENTS = '%', - COMMENT = '#' - } block; -} uc_lexer_t; - - -void uc_lexer_init(uc_lexer_t *lex, uc_parse_config_t *config, uc_source_t *source); -void uc_lexer_free(uc_lexer_t *lex); - -uc_token_t *uc_lexer_next_token(uc_lexer_t *lex); - -bool utf8enc(char **out, int *rem, int code); - -const char * -uc_get_tokenname(unsigned type); - -#endif /* __LEXER_H_ */ diff --git a/lib.c b/lib.c index ebdd1af..c61e307 100644 --- a/lib.c +++ b/lib.c @@ -32,11 +32,11 @@ #include #include -#include "lexer.h" -#include "compiler.h" -#include "vm.h" -#include "lib.h" -#include "source.h" +#include "ucode/lexer.h" +#include "ucode/compiler.h" +#include "ucode/vm.h" +#include "ucode/lib.h" +#include "ucode/source.h" static void format_context_line(uc_stringbuf_t *buf, const char *line, size_t off, bool compact) diff --git a/lib.h b/lib.h deleted file mode 100644 index 7eeae9f..0000000 --- a/lib.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __LIB_H_ -#define __LIB_H_ - -#include "vm.h" -#include "lexer.h" - -typedef struct { - const char *name; - uc_cfn_ptr_t func; -} uc_cfunction_list_t; - -extern const uc_cfunction_list_t uc_stdlib_functions[]; - -void uc_load_stdlib(uc_value_t *scope); - -bool format_source_context(uc_stringbuf_t *buf, uc_source_t *src, size_t off, bool compact); -bool format_error_context(uc_stringbuf_t *buf, uc_source_t *src, uc_value_t *stacktrace, size_t off); - - -/* vm helper */ - -static inline void * -_uc_get_self(uc_vm_t *vm, const char *expected_type) -{ - return ucv_ressource_dataptr(vm->callframes.entries[vm->callframes.count - 1].ctx, expected_type); -} - -#define uc_get_self(...) _uc_get_self(vm, __VA_ARGS__) - -static inline uc_value_t * -_uc_get_arg(uc_vm_t *vm, size_t nargs, size_t n) -{ - if (n >= nargs) - return NULL; - - return uc_vm_stack_peek(vm, nargs - n - 1); -} - -#define uc_get_arg(...) _uc_get_arg(vm, nargs, __VA_ARGS__) - -#define uc_call(nargs) uc_vm_call(vm, false, nargs) -#define uc_push_val(val) uc_vm_stack_push(vm, val) -#define uc_pop_val() uc_vm_stack_pop(vm) - - -/* value helper */ - -static inline uc_value_t * -uc_alloc_ressource(uc_ressource_type_t *type, void *data) -{ - return ucv_ressource_new(type, data); -} - -static inline uc_type_t -uc_to_number(uc_value_t *v, int64_t *n, double *d) -{ - return uc_cast_number(v, n, d); -} - -static inline double -uc_to_double(uc_value_t *v) -{ - int64_t n; - double d; - - return (uc_cast_number(v, &n, &d) == UC_DOUBLE) ? d : (double)n; -} - -static inline int64_t -uc_to_int64(uc_value_t *v) -{ - int64_t n; - double d; - - return (uc_cast_number(v, &n, &d) == UC_DOUBLE) ? (int64_t)d : n; -} - - -/* ressource type helper */ - -static inline uc_ressource_type_t * -_uc_declare_type(uc_vm_t *vm, const char *name, const uc_cfunction_list_t *list, size_t len, void (*freefn)(void *)) -{ - uc_value_t *proto = ucv_object_new(NULL); - - while (len-- > 0) - ucv_object_add(proto, list[len].name, - ucv_cfunction_new(list[len].name, list[len].func)); - - return ucv_ressource_type_add(vm, name, proto, freefn); -} - -#define uc_declare_type(vm, name, functions, freefn) \ - _uc_declare_type(vm, name, functions, ARRAY_SIZE(functions), freefn) - - -/* function helper */ - -#define uc_add_function(object, name, function) \ - ucv_object_add(object, name, ucv_cfunction_new(name, function)) - -static inline bool -_uc_add_functions(uc_value_t *object, const uc_cfunction_list_t *list, size_t len) -{ - bool rv = true; - - while (len-- > 0) - rv &= uc_add_function(object, list[len].name, list[len].func); - - return rv; -} - -#define uc_add_functions(object, functions) \ - _uc_add_functions(object, functions, ARRAY_SIZE(functions)) - -#endif /* __LIB_H_ */ diff --git a/lib/fs.c b/lib/fs.c index 7d501a2..a6a5227 100644 --- a/lib/fs.c +++ b/lib/fs.c @@ -26,7 +26,7 @@ #include #include -#include "../module.h" +#include "ucode/module.h" #define err_return(err) do { last_error = err; return NULL; } while(0) diff --git a/lib/math.c b/lib/math.c index 5ba8d76..e2c2fd8 100644 --- a/lib/math.c +++ b/lib/math.c @@ -17,7 +17,7 @@ #include #include -#include "../module.h" +#include "ucode/module.h" static bool srand_called = false; diff --git a/lib/ubus.c b/lib/ubus.c index d1b2c8c..79b615c 100644 --- a/lib/ubus.c +++ b/lib/ubus.c @@ -19,7 +19,7 @@ #include #include -#include "../module.h" +#include "ucode/module.h" #define err_return(err) do { last_error = err; return NULL; } while(0) diff --git a/lib/uci.c b/lib/uci.c index 89c5c92..116fad6 100644 --- a/lib/uci.c +++ b/lib/uci.c @@ -17,7 +17,7 @@ #include #include -#include "../module.h" +#include "ucode/module.h" #define err_return(err) do { last_error = err; return NULL; } while(0) diff --git a/main.c b/main.c index 6544a59..0229094 100644 --- a/main.c +++ b/main.c @@ -28,11 +28,11 @@ #include #endif -#include "compiler.h" -#include "lexer.h" -#include "lib.h" -#include "vm.h" -#include "source.h" +#include "ucode/compiler.h" +#include "ucode/lexer.h" +#include "ucode/lib.h" +#include "ucode/vm.h" +#include "ucode/source.h" static void diff --git a/module.h b/module.h deleted file mode 100644 index 43d9d51..0000000 --- a/module.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __MODULE_H_ -#define __MODULE_H_ - -#include "lib.h" -#include "vm.h" - -#define register_functions(scope, functions) \ - if (scope) \ - for (int i = 0; i < ARRAY_SIZE(functions); i++) \ - json_object_object_add(scope->header.jso, functions[i].name, \ - ops->value.cfunc(functions[i].name, functions[i].func)) - -#define alloc_prototype(functions) ({ \ - uc_prototype *__proto = uc_object_as_prototype(ops->value.proto(NULL)); \ - register_functions(__proto, functions); \ - __proto; \ -}) - -#define declare_type(name, proto, freefn) \ - ucv_ressource_type_add(name, proto, freefn) - -#define alloc_ressource(data, type) \ - ucv_ressource_new(ucv_object_new(NULL), type, data) - -#define register_ressource(scope, key, res) \ - json_object_object_add((scope)->header.jso, key, (res)->header.jso) - -void uc_module_init(uc_vm_t *vm, uc_value_t *scope) __attribute__((weak)); - -void uc_module_entry(uc_vm_t *vm, uc_value_t *scope); -void uc_module_entry(uc_vm_t *vm, uc_value_t *scope) -{ - if (uc_module_init) - uc_module_init(vm, scope); -} - -#endif /* __MODULE_H_ */ diff --git a/source.c b/source.c index e5a924f..b7bb96d 100644 --- a/source.c +++ b/source.c @@ -16,7 +16,7 @@ #include -#include "source.h" +#include "ucode/source.h" uc_source_t * diff --git a/source.h b/source.h deleted file mode 100644 index 3de7c93..0000000 --- a/source.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __SOURCE_H_ -#define __SOURCE_H_ - -#include -#include -#include - -#include "util.h" -#include "types.h" - - -uc_source_t *uc_source_new_file(const char *path); -uc_source_t *uc_source_new_buffer(const char *name, char *buf, size_t len); - -size_t uc_source_get_line(uc_source_t *source, size_t *offset); - -uc_source_t *uc_source_get(uc_source_t *source); -void uc_source_put(uc_source_t *source); - -#endif /* __SOURCE_H_ */ diff --git a/types.c b/types.c index 5808d8e..e888687 100644 --- a/types.c +++ b/types.c @@ -21,9 +21,9 @@ #include #include -#include "types.h" -#include "util.h" -#include "vm.h" +#include "ucode/types.h" +#include "ucode/util.h" +#include "ucode/vm.h" uc_type_t ucv_type(uc_value_t *uv) diff --git a/types.h b/types.h deleted file mode 100644 index e2cb15d..0000000 --- a/types.h +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) 2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __TYPES_H_ -#define __TYPES_H_ - -#include -#include -#include -#include - -#include "util.h" - - -/* Value types and generic value header */ - -typedef enum uc_type { - UC_NULL, - UC_INTEGER, - UC_BOOLEAN, - UC_STRING, - UC_DOUBLE, - UC_ARRAY, - UC_OBJECT, - UC_REGEXP, - UC_FUNCTION, - UC_CFUNCTION, - UC_CLOSURE, - UC_UPVALUE, - UC_RESSOURCE -} uc_type_t; - -typedef struct uc_value { - uint32_t type:4; - uint32_t mark:1; - uint32_t u64:1; - uint32_t refcount:26; -} uc_value_t; - - -/* Constant list defintions */ - -typedef struct { - size_t isize; - size_t dsize; - uint64_t *index; - char *data; -} uc_value_list_t; - - -/* Source buffer defintions */ - -uc_declare_vector(uc_lineinfo_t, uint8_t); - -typedef struct { - char *filename, *buffer; - FILE *fp; - size_t usecount, off; - uc_lineinfo_t lineinfo; -} uc_source_t; - - -/* Bytecode chunk defintions */ - -typedef struct { - size_t from, to, target, slot; -} uc_ehrange_t; - -typedef struct { - size_t from, to, slot, nameidx; -} uc_varrange_t; - -uc_declare_vector(uc_ehranges_t, uc_ehrange_t); -uc_declare_vector(uc_variables_t, uc_varrange_t); -uc_declare_vector(uc_offsetinfo_t, uint8_t); - -typedef struct { - size_t count; - uint8_t *entries; - uc_value_list_t constants; - uc_ehranges_t ehranges; - struct { - uc_variables_t variables; - uc_value_list_t varnames; - uc_offsetinfo_t offsets; - } debuginfo; -} uc_chunk_t; - - -/* Value type structures */ - -typedef struct uc_weakref { - struct uc_weakref *prev; - struct uc_weakref *next; -} uc_weakref_t; - -typedef struct { - uc_value_t header; - double dbl; -} uc_double_t; - -typedef struct { - uc_value_t header; - union { - int64_t s64; - uint64_t u64; - } i; -} uc_integer_t; - -typedef struct { - uc_value_t header; - size_t length; - char str[]; -} uc_string_t; - -typedef struct { - uc_value_t header; - uc_weakref_t ref; - size_t count; - uc_value_t *proto; - uc_value_t **entries; -} uc_array_t; - -typedef struct { - uc_value_t header; - uc_weakref_t ref; - uc_value_t *proto; - struct lh_table *table; -} uc_object_t; - -typedef struct { - uc_value_t header; - regex_t regexp; - bool icase, newline, global; - char source[]; -} uc_regexp_t; - -typedef struct { - uc_value_t header; - bool arrow, vararg, strict; - size_t nargs; - size_t nupvals; - size_t srcpos; - uc_chunk_t chunk; - uc_source_t *source; - char name[]; -} uc_function_t; - -typedef struct uc_upval_tref { - uc_value_t header; - size_t slot; - bool closed; - uc_value_t *value; - struct uc_upval_tref *next; -} uc_upval_tref_t; - -typedef struct { - uc_value_t header; - uc_weakref_t ref; - bool is_arrow; - uc_function_t *function; - uc_upval_tref_t **upvals; -} uc_closure_t; - -typedef struct uc_vm uc_vm_t; -typedef uc_value_t *(*uc_cfn_ptr_t)(uc_vm_t *, size_t); - -typedef struct { - uc_value_t header; - uc_cfn_ptr_t cfn; - char name[]; -} uc_cfunction_t; - -typedef struct { - const char *name; - uc_value_t *proto; - void (*free)(void *); -} uc_ressource_type_t; - -typedef struct { - uc_value_t header; - uc_ressource_type_t *type; - void *data; -} uc_ressource_t; - -uc_declare_vector(uc_ressource_types_t, uc_ressource_type_t *); - - -/* Parser definitions */ - -typedef struct { - bool lstrip_blocks; - bool trim_blocks; - bool strict_declarations; - bool raw_mode; -} uc_parse_config_t; - - -/* VM definitions */ - -typedef enum { - EXCEPTION_NONE, - EXCEPTION_SYNTAX, - EXCEPTION_RUNTIME, - EXCEPTION_TYPE, - EXCEPTION_REFERENCE, - EXCEPTION_USER, - EXCEPTION_EXIT -} uc_exception_type_t; - -typedef struct { - uc_exception_type_t type; - uc_value_t *stacktrace; - char *message; -} uc_exception_t; - -typedef struct { - uint8_t *ip; - uc_closure_t *closure; - uc_cfunction_t *cfunction; - size_t stackframe; - uc_value_t *ctx; - bool mcall, strict; -} uc_callframe_t; - -uc_declare_vector(uc_callframes_t, uc_callframe_t); -uc_declare_vector(uc_stack_t, uc_value_t *); - -typedef struct printbuf uc_stringbuf_t; - -typedef void (uc_exception_handler_t)(uc_vm_t *, uc_exception_t *); - -struct uc_vm { - uc_stack_t stack; - uc_exception_t exception; - uc_callframes_t callframes; - uc_upval_tref_t *open_upvals; - uc_parse_config_t *config; - uc_value_t *globals; - uc_source_t *sources; - uc_weakref_t values; - uc_ressource_types_t restypes; - union { - uint32_t u32; - int32_t s32; - uint16_t u16; - int16_t s16; - uint8_t u8; - int8_t s8; - } arg; - size_t spread_values; - uint8_t trace; - uc_stringbuf_t *strbuf; - uc_exception_handler_t *exhandler; - FILE *output; -}; - - -/* Value API */ - -void ucv_free(uc_value_t *, bool); -void ucv_put(uc_value_t *); - -uc_value_t *ucv_get(uc_value_t *uv); - -uc_type_t ucv_type(uc_value_t *); -const char *ucv_typename(uc_value_t *); - -uc_value_t *ucv_boolean_new(bool); -bool ucv_boolean_get(uc_value_t *); - -uc_value_t *ucv_string_new(const char *); -uc_value_t *ucv_string_new_length(const char *, size_t); -size_t ucv_string_length(uc_value_t *); - -char *_ucv_string_get(uc_value_t **); -#define ucv_string_get(uv) _ucv_string_get((uc_value_t **)&uv) - -uc_stringbuf_t *ucv_stringbuf_new(void); -uc_value_t *ucv_stringbuf_finish(uc_stringbuf_t *); - -void _ucv_stringbuf_append(uc_stringbuf_t *, const char *, size_t); - -#define _ucv_is_literal(str) ("" str) -#define ucv_stringbuf_append(buf, str) _ucv_stringbuf_append(buf, _ucv_is_literal(str), sizeof(str) - 1) -#define ucv_stringbuf_addstr(buf, str, len) _ucv_stringbuf_append(buf, str, len) -#define ucv_stringbuf_printf(buf, fmt, ...) sprintbuf(buf, fmt, __VA_ARGS__) - -uc_value_t *ucv_int64_new(int64_t); -uc_value_t *ucv_uint64_new(uint64_t); -int64_t ucv_int64_get(uc_value_t *); -uint64_t ucv_uint64_get(uc_value_t *); - -uc_value_t *ucv_double_new(double); -double ucv_double_get(uc_value_t *); - -uc_value_t *ucv_array_new(uc_vm_t *); -uc_value_t *ucv_array_new_length(uc_vm_t *, size_t); -uc_value_t *ucv_array_get(uc_value_t *, size_t); -uc_value_t *ucv_array_pop(uc_value_t *); -uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *); -uc_value_t *ucv_array_shift(uc_value_t *); -uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *); -void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *)); -bool ucv_array_delete(uc_value_t *, size_t, size_t); -bool ucv_array_set(uc_value_t *, size_t, uc_value_t *); -size_t ucv_array_length(uc_value_t *); - -uc_value_t *ucv_object_new(uc_vm_t *); -uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *); -bool ucv_object_add(uc_value_t *, const char *, uc_value_t *); -bool ucv_object_delete(uc_value_t *, const char *); -size_t ucv_object_length(uc_value_t *); - -#define ucv_object_foreach(obj, key, val) \ - char *key = NULL; \ - uc_value_t *val = NULL; \ - struct lh_entry *entry##key; \ - struct lh_entry *entry_next##key = NULL; \ - for (entry##key = (ucv_type(obj) == UC_OBJECT) ? ((uc_object_t *)obj)->table->head : NULL; \ - (entry##key ? (key = (char *)lh_entry_k(entry##key), \ - val = (uc_value_t *)lh_entry_v(entry##key), \ - entry_next##key = entry##key->next, entry##key) \ - : 0); \ - entry##key = entry_next##key) - -uc_value_t *ucv_function_new(const char *, size_t, uc_source_t *); -size_t ucv_function_srcpos(uc_value_t *, size_t); - -uc_value_t *ucv_cfunction_new(const char *, uc_cfn_ptr_t); - -uc_value_t *ucv_closure_new(uc_vm_t *, uc_function_t *, bool); - -uc_ressource_type_t *ucv_ressource_type_add(uc_vm_t *, const char *, uc_value_t *, void (*)(void *)); -uc_ressource_type_t *ucv_ressource_type_lookup(uc_vm_t *, const char *); - -uc_value_t *ucv_ressource_new(uc_ressource_type_t *, void *); -void **ucv_ressource_dataptr(uc_value_t *, const char *); - -uc_value_t *ucv_regexp_new(const char *, bool, bool, bool, char **); - -uc_value_t *ucv_upvalref_new(size_t); - -uc_value_t *ucv_prototype_get(uc_value_t *); -bool ucv_prototype_set(uc_value_t *, uc_value_t *); - -uc_value_t *ucv_property_get(uc_value_t *, const char *); - -uc_value_t *ucv_from_json(uc_vm_t *, json_object *); -json_object *ucv_to_json(uc_value_t *); - -char *ucv_to_string(uc_vm_t *, uc_value_t *); -char *ucv_to_jsonstring_formatted(uc_vm_t *, uc_value_t *, char, size_t); -void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_t, char, size_t); - -#define ucv_to_jsonstring(vm, val) ucv_to_jsonstring_formatted(vm, val, '\1', 0) -#define ucv_to_stringbuf(vm, buf, val, json) ucv_to_stringbuf_formatted(vm, buf, val, 0, json ? '\1' : '\0', 0) - -static inline bool -ucv_is_callable(uc_value_t *uv) -{ - switch (ucv_type(uv)) { - case UC_CLOSURE: - case UC_CFUNCTION: - return true; - - default: - return false; - } -} - -static inline bool -ucv_is_arrowfn(uc_value_t *uv) -{ - uc_closure_t *closure = (uc_closure_t *)uv; - - return (ucv_type(uv) == UC_CLOSURE && closure->is_arrow); -} - -static inline bool -ucv_is_u64(uc_value_t *uv) -{ - return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->u64 == true); -} - -static inline bool -ucv_is_scalar(uc_value_t *uv) -{ - switch (ucv_type(uv)) { - case UC_NULL: - case UC_BOOLEAN: - case UC_DOUBLE: - case UC_INTEGER: - case UC_STRING: - return true; - - default: - return false; - } -} - -static inline bool -ucv_is_marked(uc_value_t *uv) -{ - return (((uintptr_t)uv & 3) == 0 && uv != NULL && uv->mark == true); -} - -static inline void -ucv_set_mark(uc_value_t *uv) -{ - if (((uintptr_t)uv & 3) == 0 && uv != NULL) - uv->mark = true; -} - -static inline void -ucv_clear_mark(uc_value_t *uv) -{ - if (((uintptr_t)uv & 3) == 0 && uv != NULL) - uv->mark = false; -} - -bool ucv_equal(uc_value_t *, uc_value_t *); - -void ucv_gc(uc_vm_t *, bool); - -#endif /* __TYPES_H_ */ diff --git a/util.h b/util.h deleted file mode 100644 index 858a3fd..0000000 --- a/util.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __UTIL_H_ -#define __UTIL_H_ - -#include -#include -#include -#include -#include /* va_start(), va_end(), va_list */ -#include /* strdup() */ -#include - - -/* alignment & array size */ - -#ifndef ALIGN -#define ALIGN(x) (((x) + sizeof(size_t) - 1) & -sizeof(size_t)) -#endif - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -#endif - - -/* vector macros */ - -#define UC_VECTOR_CHUNK_SIZE 8 - -#define uc_declare_vector(name, type) \ - typedef struct { \ - size_t count; \ - type *entries; \ - } name - -#define uc_vector_grow(vec) \ - do { \ - if (((vec)->count % UC_VECTOR_CHUNK_SIZE) == 0) { \ - (vec)->entries = xrealloc((vec)->entries, sizeof((vec)->entries[0]) * ((vec)->count + UC_VECTOR_CHUNK_SIZE)); \ - memset(&(vec)->entries[(vec)->count], 0, sizeof((vec)->entries[0]) * UC_VECTOR_CHUNK_SIZE); \ - } \ - } while(0) - -#define uc_vector_clear(vec) \ - do { \ - free((vec)->entries); \ - (vec)->entries = NULL; \ - (vec)->count = 0; \ - } while(0) - -#define uc_vector_first(vec) \ - (&((vec)->entries[0])) - -#define uc_vector_last(vec) \ - (&((vec)->entries[(vec)->count - 1])) - - -/* "failsafe" utility functions */ - -static inline void *xalloc(size_t size) { - void *ptr = calloc(1, size); - - if (!ptr) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return ptr; -} - -static inline void *xrealloc(void *ptr, size_t size) { - ptr = realloc(ptr, size); - - if (!ptr) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return ptr; -} - -static inline char *xstrdup(const char *s) { - char *ptr = strdup(s); - - if (!ptr) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return ptr; -} - -static inline struct json_tokener *xjs_new_tokener(void) { - struct json_tokener *tok = json_tokener_new(); - - if (!tok) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return tok; -} - -__attribute__((format(printf, 2, 0))) -static inline int xasprintf(char **strp, const char *fmt, ...) { - va_list ap; - int len; - - va_start(ap, fmt); - len = vasprintf(strp, fmt, ap); - va_end(ap); - - if (len == -1) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return len; -} - -__attribute__((format(printf, 2, 0))) -static inline int xvasprintf(char **strp, const char *fmt, va_list ap) { - int len = vasprintf(strp, fmt, ap); - - if (len == -1) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return len; -} - -static inline struct printbuf *xprintbuf_new(void) { - struct printbuf *pb = printbuf_new(); - - if (!pb) { - fprintf(stderr, "Out of memory\n"); - abort(); - } - - return pb; -} - -#endif /* __UTIL_H_ */ diff --git a/value.c b/value.c index b72ba8c..c27470f 100644 --- a/value.c +++ b/value.c @@ -20,10 +20,10 @@ #include /* isspace(), isdigit(), isxdigit() */ #include -#include "util.h" -#include "chunk.h" -#include "value.h" -#include "vm.h" +#include "ucode/util.h" +#include "ucode/chunk.h" +#include "ucode/value.h" +#include "ucode/vm.h" #define TAG_TYPE uint64_t #define TAG_BITS 3 diff --git a/value.h b/value.h deleted file mode 100644 index 04d37a9..0000000 --- a/value.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __VALUE_H_ -#define __VALUE_H_ - -#include -#include -#include - -#ifdef JSONC - #include -#else - #include -#endif - -#include - -#include "types.h" - -typedef enum { - TAG_INVAL = 0, - TAG_NUM = 1, - TAG_LNUM = 2, - TAG_DBL = 3, - TAG_STR = 4, - TAG_LSTR = 5, - TAG_PTR = 6 -} uc_value_type_t; - -bool uc_cmp(int how, uc_value_t *v1, uc_value_t *v2); -bool uc_val_is_truish(uc_value_t *val); - -uc_type_t uc_cast_number(uc_value_t *v, int64_t *n, double *d); - -uc_value_t *uc_getval(uc_vm_t *, uc_value_t *scope, uc_value_t *key); -uc_value_t *uc_setval(uc_vm_t *, uc_value_t *scope, uc_value_t *key, uc_value_t *val); -bool uc_delval(uc_vm_t *, uc_value_t *scope, uc_value_t *key); - -void uc_vallist_init(uc_value_list_t *list); -void uc_vallist_free(uc_value_list_t *list); - -ssize_t uc_vallist_add(uc_value_list_t *list, uc_value_t *value); -uc_value_type_t uc_vallist_type(uc_value_list_t *list, size_t idx); -uc_value_t *uc_vallist_get(uc_value_list_t *list, size_t idx); - -#endif /* __VALUE_H_ */ diff --git a/vm.c b/vm.c index 443c64e..79838f9 100644 --- a/vm.c +++ b/vm.c @@ -20,9 +20,9 @@ #include #include -#include "vm.h" -#include "compiler.h" -#include "lib.h" /* format_error_context() */ +#include "ucode/vm.h" +#include "ucode/compiler.h" +#include "ucode/lib.h" /* format_error_context() */ #undef __insn #define __insn(_name) #_name, diff --git a/vm.h b/vm.h deleted file mode 100644 index 553cf61..0000000 --- a/vm.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2020-2021 Jo-Philipp Wich - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __VM_H_ -#define __VM_H_ - -#include -#include - -#include "chunk.h" -#include "util.h" -#include "lexer.h" -#include "types.h" - -#define __insns \ -__insn(NOOP) \ -__insn(LOAD) \ -__insn(LOAD8) \ -__insn(LOAD16) \ -__insn(LOAD32) \ -__insn(LTHIS) \ -__insn(LREXP) \ -__insn(LNULL) \ -__insn(LTRUE) \ -__insn(LFALSE) \ -__insn(LLOC) \ -__insn(LUPV) \ -__insn(LVAR) \ -__insn(LVAL) \ -__insn(CLFN) \ -__insn(ARFN) \ -__insn(SLOC) \ -__insn(SUPV) \ -__insn(SVAR) \ -__insn(SVAL) \ -__insn(ULOC) \ -__insn(UUPV) \ -__insn(UVAR) \ -__insn(UVAL) \ -__insn(NARR) \ -__insn(PARR) \ -__insn(MARR) \ -__insn(NOBJ) \ -__insn(SOBJ) \ -__insn(MOBJ) \ -__insn(BOR) \ -__insn(BXOR) \ -__insn(BAND) \ -__insn(EQS) \ -__insn(NES) \ -__insn(EQ) \ -__insn(NE) \ -__insn(LT) \ -__insn(LE) \ -__insn(GT) \ -__insn(GE) \ -__insn(IN) \ -__insn(LSHIFT) \ -__insn(RSHIFT) \ -__insn(ADD) \ -__insn(SUB) \ -__insn(MUL) \ -__insn(DIV) \ -__insn(MOD) \ -__insn(NOT) \ -__insn(COMPL) \ -__insn(PLUS) \ -__insn(MINUS) \ -__insn(JMP) \ -__insn(JMPZ) \ -__insn(COPY) \ -__insn(POP) \ -__insn(CUPV) \ -__insn(RETURN) \ -__insn(CALL) \ -__insn(MCALL) \ -__insn(PRINT) \ -__insn(NEXTK) \ -__insn(NEXTKV) \ -__insn(DELETE) - - -#undef __insn -#define __insn(_name) I_##_name, - -typedef enum { - __insns - __I_MAX -} uc_vm_insn_t; - -typedef enum { - STATUS_OK, - STATUS_EXIT, - ERROR_COMPILE, - ERROR_RUNTIME -} uc_vm_status_t; - -extern uint32_t insns[__I_MAX]; - -void uc_vm_init(uc_vm_t *vm, uc_parse_config_t *config); -void uc_vm_free(uc_vm_t *vm); - -uc_value_t *uc_vm_scope_get(uc_vm_t *vm); -void uc_vm_scope_set(uc_vm_t *vm, uc_value_t *ctx); - -void uc_vm_stack_push(uc_vm_t *vm, uc_value_t *value); -uc_value_t *uc_vm_stack_pop(uc_vm_t *vm); -uc_value_t *uc_vm_stack_peek(uc_vm_t *vm, size_t offset); - -uc_exception_handler_t *uc_vm_exception_handler_get(uc_vm_t *vm); -void uc_vm_exception_handler_set(uc_vm_t *vm, uc_exception_handler_t *exhandler); - -uint32_t uc_vm_trace_get(uc_vm_t *vm); -void uc_vm_trace_set(uc_vm_t *vm, uint32_t level); - -uc_exception_type_t uc_vm_call(uc_vm_t *vm, bool mcall, size_t nargs); - -void __attribute__((format(printf, 3, 0))) -uc_vm_raise_exception(uc_vm_t *vm, uc_exception_type_t type, const char *fmt, ...); - -uc_vm_status_t uc_vm_execute(uc_vm_t *vm, uc_function_t *fn, uc_value_t **retval); -uc_value_t *uc_vm_invoke(uc_vm_t *vm, const char *fname, size_t nargs, ...); - -#endif /* __VM_H_ */ -- cgit v1.2.3