| |
| /* |
| * Copyright (C) Igor Sysoev |
| * Copyright (C) NGINX, Inc. |
| */ |
| |
| #ifndef _NJS_VMCODE_H_INCLUDED_ |
| #define _NJS_VMCODE_H_INCLUDED_ |
| |
| |
| /* |
| * Negative return values handled by nJSVM interpreter as special events. |
| * The values must be in range from -1 to -11, because -12 is minimal jump |
| * offset on 32-bit platforms. |
| * 0 (NJS_OK) : njs_vmcode_stop() has stopped execution, |
| * execution successfully finished |
| * -1 (NJS_ERROR): error or exception; |
| * -2 .. -11: not used. |
| */ |
| |
| /* The last return value which preempts execution. */ |
| #define NJS_PREEMPT (-11) |
| |
| |
| typedef intptr_t njs_jump_off_t; |
| typedef uint8_t njs_vmcode_operation_t; |
| |
| |
| #define NJS_VMCODE_3OPERANDS 0 |
| #define NJS_VMCODE_2OPERANDS 1 |
| |
| |
| enum { |
| NJS_VMCODE_MOVE_ARG = 0, |
| NJS_VMCODE_STOP, |
| NJS_VMCODE_JUMP, |
| NJS_VMCODE_PROPERTY_SET, |
| NJS_VMCODE_PROPERTY_ACCESSOR, |
| NJS_VMCODE_IF_TRUE_JUMP, |
| NJS_VMCODE_IF_FALSE_JUMP, |
| NJS_VMCODE_IF_EQUAL_JUMP, |
| NJS_VMCODE_PROPERTY_INIT, |
| NJS_VMCODE_RETURN, |
| NJS_VMCODE_FUNCTION_COPY, |
| NJS_VMCODE_FUNCTION_FRAME, |
| NJS_VMCODE_METHOD_FRAME, |
| NJS_VMCODE_FUNCTION_CALL, |
| NJS_VMCODE_PROPERTY_NEXT, |
| NJS_VMCODE_THIS, |
| NJS_VMCODE_ARGUMENTS, |
| NJS_VMCODE_PROTO_INIT, |
| NJS_VMCODE_IMPORT, |
| |
| NJS_VMCODE_AWAIT, |
| |
| NJS_VMCODE_TRY_START, |
| NJS_VMCODE_THROW, |
| NJS_VMCODE_TRY_BREAK, |
| NJS_VMCODE_TRY_CONTINUE, |
| NJS_VMCODE_TRY_END, |
| NJS_VMCODE_CATCH, |
| NJS_VMCODE_FINALLY, |
| |
| NJS_VMCODE_LET, |
| NJS_VMCODE_LET_UPDATE, |
| NJS_VMCODE_INITIALIZATION_TEST, |
| NJS_VMCODE_NOT_INITIALIZED, |
| NJS_VMCODE_ASSIGNMENT_ERROR, |
| |
| NJS_VMCODE_ERROR, |
| |
| NJS_VMCODE_NORET = 127 |
| }; |
| |
| |
| enum { |
| NJS_VMCODE_MOVE = NJS_VMCODE_NORET + 1, |
| NJS_VMCODE_PROPERTY_GET, |
| NJS_VMCODE_INCREMENT, |
| NJS_VMCODE_POST_INCREMENT, |
| NJS_VMCODE_DECREMENT, |
| NJS_VMCODE_POST_DECREMENT, |
| NJS_VMCODE_TRY_RETURN, |
| NJS_VMCODE_GLOBAL_GET, |
| |
| NJS_VMCODE_LESS, |
| NJS_VMCODE_GREATER, |
| NJS_VMCODE_LESS_OR_EQUAL, |
| NJS_VMCODE_GREATER_OR_EQUAL, |
| NJS_VMCODE_ADDITION, |
| NJS_VMCODE_EQUAL, |
| NJS_VMCODE_NOT_EQUAL, |
| |
| NJS_VMCODE_SUBSTRACTION, |
| NJS_VMCODE_MULTIPLICATION, |
| NJS_VMCODE_EXPONENTIATION, |
| NJS_VMCODE_DIVISION, |
| NJS_VMCODE_REMAINDER, |
| NJS_VMCODE_BITWISE_AND, |
| NJS_VMCODE_BITWISE_OR, |
| NJS_VMCODE_BITWISE_XOR, |
| NJS_VMCODE_LEFT_SHIFT, |
| NJS_VMCODE_RIGHT_SHIFT, |
| NJS_VMCODE_UNSIGNED_RIGHT_SHIFT, |
| NJS_VMCODE_OBJECT_COPY, |
| NJS_VMCODE_TEMPLATE_LITERAL, |
| NJS_VMCODE_PROPERTY_IN, |
| NJS_VMCODE_PROPERTY_DELETE, |
| NJS_VMCODE_PROPERTY_FOREACH, |
| |
| NJS_VMCODE_STRICT_EQUAL, |
| NJS_VMCODE_STRICT_NOT_EQUAL, |
| |
| NJS_VMCODE_TEST_IF_TRUE, |
| NJS_VMCODE_TEST_IF_FALSE, |
| |
| NJS_VMCODE_COALESCE, |
| |
| NJS_VMCODE_UNARY_PLUS, |
| NJS_VMCODE_UNARY_NEGATION, |
| NJS_VMCODE_BITWISE_NOT, |
| NJS_VMCODE_LOGICAL_NOT, |
| NJS_VMCODE_OBJECT, |
| NJS_VMCODE_ARRAY, |
| NJS_VMCODE_FUNCTION, |
| NJS_VMCODE_REGEXP, |
| |
| NJS_VMCODE_INSTANCE_OF, |
| NJS_VMCODE_TYPEOF, |
| NJS_VMCODE_VOID, |
| NJS_VMCODE_DELETE, |
| NJS_VMCODE_DEBUGGER, |
| |
| NJS_VMCODE_NOP = 255 |
| }; |
| |
| |
| typedef struct { |
| njs_vmcode_operation_t operation; |
| uint8_t operands; /* 2 bits */ |
| } njs_vmcode_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t operand1; |
| njs_index_t operand2; |
| njs_index_t operand3; |
| } njs_vmcode_generic_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t index; |
| } njs_vmcode_1addr_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t dst; |
| njs_index_t src; |
| } njs_vmcode_2addr_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t dst; |
| njs_index_t src1; |
| njs_index_t src2; |
| } njs_vmcode_3addr_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t dst; |
| njs_index_t src; |
| } njs_vmcode_move_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_object_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t dst; |
| } njs_vmcode_this_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t dst; |
| } njs_vmcode_arguments_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| uintptr_t length; |
| uint8_t ctor; /* 1 bit */ |
| } njs_vmcode_array_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_template_literal_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_function_lambda_t *lambda; |
| njs_bool_t async; |
| } njs_vmcode_function_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_regexp_pattern_t *pattern; |
| } njs_vmcode_regexp_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_index_t object; |
| } njs_vmcode_object_copy_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| } njs_vmcode_jump_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| njs_index_t cond; |
| } njs_vmcode_cond_jump_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| njs_index_t value1; |
| njs_index_t value2; |
| } njs_vmcode_equal_jump_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_index_t value; |
| njs_jump_off_t offset; |
| } njs_vmcode_test_jump_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t value; |
| njs_index_t object; |
| njs_index_t property; |
| } njs_vmcode_prop_get_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t value; |
| njs_index_t object; |
| njs_index_t property; |
| } njs_vmcode_prop_set_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t value; |
| njs_index_t object; |
| njs_index_t property; |
| uint8_t type; |
| } njs_vmcode_prop_accessor_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t next; |
| njs_index_t object; |
| njs_jump_off_t offset; |
| } njs_vmcode_prop_foreach_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_index_t object; |
| njs_index_t next; |
| njs_jump_off_t offset; |
| } njs_vmcode_prop_next_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t value; |
| njs_index_t constructor; |
| njs_index_t object; |
| } njs_vmcode_instance_of_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t nargs; |
| njs_index_t name; |
| uint8_t ctor; /* 1 bit */ |
| } njs_vmcode_function_frame_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t nargs; |
| njs_index_t object; |
| njs_index_t method; |
| uint8_t ctor; /* 1 bit */ |
| } njs_vmcode_method_frame_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_function_call_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_return_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_stop_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| njs_index_t exception_value; |
| njs_index_t exit_value; |
| } njs_vmcode_try_start_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| njs_index_t exit_value; |
| } njs_vmcode_try_trampoline_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| njs_index_t exception; |
| } njs_vmcode_catch_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_throw_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_jump_off_t offset; |
| } njs_vmcode_try_end_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t save; |
| njs_index_t retval; |
| njs_jump_off_t offset; |
| } njs_vmcode_try_return_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_index_t exit_value; |
| njs_jump_off_t continue_offset; |
| njs_jump_off_t break_offset; |
| } njs_vmcode_finally_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_object_type_t type; |
| union { |
| njs_str_t name; |
| njs_str_t message; |
| } u; |
| } njs_vmcode_error_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t src; |
| njs_uint_t dst; |
| } njs_vmcode_move_arg_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_value_t *function; |
| njs_index_t retval; |
| } njs_vmcode_function_copy_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| njs_mod_t *module; |
| } njs_vmcode_import_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t dst; |
| } njs_vmcode_variable_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_debugger_t; |
| |
| |
| typedef struct { |
| njs_vmcode_t code; |
| njs_index_t retval; |
| } njs_vmcode_await_t; |
| |
| |
| njs_int_t njs_vmcode_interpreter(njs_vm_t *vm, u_char *pc, |
| void *promise_cap, void *async_ctx); |
| |
| njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor); |
| |
| #ifdef NJS_OPCODE_DEBUG |
| #define njs_vmcode_debug(vm, pc, prefix) { \ |
| do { \ |
| njs_vm_code_t *code; \ |
| \ |
| code = njs_lookup_code(vm, pc); \ |
| \ |
| njs_printf("%s %V\n", prefix, \ |
| (code != NULL) ? &code->name : &njs_entry_unknown); \ |
| } while (0); \ |
| } |
| #else |
| #define njs_vmcode_debug(vm, pc, prefix) |
| #endif |
| |
| #endif /* _NJS_VMCODE_H_INCLUDED_ */ |