From: Igor Sysoev Date: Wed, 25 Nov 2015 14:22:41 +0000 (+0300) Subject: nJSVM disassembler changes. X-Git-Tag: 0.1.0~109 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=0a7b7a831740249dabd392945fa5112471a93af8;p=njs.git nJSVM disassembler changes. --- diff --git a/Makefile b/Makefile index b6c7a20e..baad353d 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ all: test lib_test test: \ $(NXT_BUILDDIR)/njs_unit_test \ - $(NXT_BUILDDIR)/njs_unit_test + $(NXT_BUILDDIR)/njs_unit_test d clean: rm -rf $(NXT_BUILDDIR) diff --git a/njs/njs_array.c b/njs/njs_array.c index d336d522..a01f9b23 100644 --- a/njs/njs_array.c +++ b/njs/njs_array.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/njs/njs_disassembler.c b/njs/njs_disassembler.c index e234a6fd..b7d9db5a 100644 --- a/njs/njs_disassembler.c +++ b/njs/njs_disassembler.c @@ -16,6 +16,10 @@ #include #include #include +#include + + +static void njs_disassemble(u_char *start, u_char *end); typedef struct { @@ -29,8 +33,6 @@ static njs_code_name_t code_names[] = { { njs_vmcode_object_create, sizeof(njs_vmcode_object_t), nxt_string("OBJECT CREATE ") }, - { njs_vmcode_array_create, sizeof(njs_vmcode_array_t), - nxt_string("ARRAY CREATE ") }, { njs_vmcode_function_create, sizeof(njs_vmcode_function_create_t), nxt_string("FUNCTION CREATE ") }, { njs_vmcode_regexp_create, sizeof(njs_vmcode_regexp_t), @@ -44,21 +46,17 @@ static njs_code_name_t code_names[] = { nxt_string("PROPERTY IN ") }, { njs_vmcode_property_delete, sizeof(njs_vmcode_3addr_t), nxt_string("PROPERTY DELETE ") }, - { njs_vmcode_property_each_start, sizeof(njs_vmcode_prop_start_t), - nxt_string("PROPERTY START ") }, - { njs_vmcode_property_each, sizeof(njs_vmcode_prop_each_t), - nxt_string("PROPERTY EACH ") }, { njs_vmcode_instance_of, sizeof(njs_vmcode_instance_of_t), nxt_string("INSTANCE OF ") }, { njs_vmcode_function, sizeof(njs_vmcode_function_t), nxt_string("FUNCTION ") }, - { njs_vmcode_method, sizeof(njs_vmcode_method_t), - nxt_string("METHOD ") }, { njs_vmcode_call, sizeof(njs_vmcode_call_t), nxt_string("CALL ") }, { njs_vmcode_return, sizeof(njs_vmcode_stop_t), nxt_string("RETURN ") }, + { njs_vmcode_stop, sizeof(njs_vmcode_stop_t), + nxt_string("STOP ") }, { njs_vmcode_increment, sizeof(njs_vmcode_3addr_t), nxt_string("INC ") }, @@ -138,23 +136,8 @@ static njs_code_name_t code_names[] = { { njs_vmcode_validate, sizeof(njs_vmcode_validate_t), nxt_string("VALIDATE ") }, - { njs_vmcode_if_true_jump, sizeof(njs_vmcode_cond_jump_t), - nxt_string("JUMP IF TRUE ") }, - { njs_vmcode_if_false_jump, sizeof(njs_vmcode_cond_jump_t), - nxt_string("JUMP IF FALSE ") }, - { njs_vmcode_jump, sizeof(njs_vmcode_jump_t), - nxt_string("JUMP ") }, - { njs_vmcode_stop, sizeof(njs_vmcode_stop_t), - nxt_string("STOP ") }, - - { njs_vmcode_try_start, sizeof(njs_vmcode_try_start_t), - nxt_string("TRY START ") }, - { njs_vmcode_try_end, sizeof(njs_vmcode_try_end_t), - nxt_string("TRY END ") }, { njs_vmcode_throw, sizeof(njs_vmcode_throw_t), nxt_string("THROW ") }, - { njs_vmcode_catch, sizeof(njs_vmcode_catch_t), - nxt_string("CATCH ") }, { njs_vmcode_finally, sizeof(njs_vmcode_finally_t), nxt_string("FINALLY ") }, @@ -162,30 +145,150 @@ static njs_code_name_t code_names[] = { void -njs_disassembler(u_char *start, u_char *end, nxt_str_t *text) +njs_disassembler(njs_vm_t *vm) { - u_char *p; - nxt_uint_t n; - nxt_str_t *name; - njs_vmcode_1addr_t *code1; - njs_vmcode_2addr_t *code2; - njs_vmcode_3addr_t *code3; - njs_vmcode_method_t *method; - njs_code_name_t *code_name; - njs_vmcode_operation_t operation; - - static nxt_str_t unknown = nxt_string("UNKOWN"); - - (void) name; - (void) code1; - (void) code2; - (void) code3; - (void) method; + nxt_uint_t n; + njs_vm_code_t *code; + + code = vm->code->start; + n = vm->code->items; + + while(n != 0) { + njs_disassemble(code->start, code->end); + code++; + n--; + } +} + + +static void +njs_disassemble(u_char *start, u_char *end) +{ + u_char *p; + nxt_str_t *name; + nxt_uint_t n; + const char *sign; + njs_code_name_t *code_name; + njs_vmcode_jump_t *jump; + njs_vmcode_1addr_t *code1; + njs_vmcode_2addr_t *code2; + njs_vmcode_3addr_t *code3; + njs_vmcode_array_t *array; + njs_vmcode_catch_t *catch; + njs_vmcode_method_t *method; + njs_vmcode_try_end_t *try_end; + njs_vmcode_try_start_t *try_start; + njs_vmcode_operation_t operation; + njs_vmcode_cond_jump_t *cond_jump; + njs_vmcode_prop_each_t *each; + njs_vmcode_prop_start_t *prop_start; p = start; while (p < end) { operation = *(njs_vmcode_operation_t *) p; + + if (operation == njs_vmcode_array_create) { + array = (njs_vmcode_array_t *) p; + p += sizeof(njs_vmcode_array_t); + + printf("ARRAY CREATE %04lX %ld\n", + array->retval, array->length); + + continue; + } + + if (operation == njs_vmcode_if_true_jump) { + cond_jump = (njs_vmcode_cond_jump_t *) p; + p += sizeof(njs_vmcode_cond_jump_t); + sign = (cond_jump->offset >= 0) ? "+" : ""; + + printf("JUMP IF TRUE %04lX %s%ld\n", + cond_jump->cond, sign, cond_jump->offset); + + continue; + } + + if (operation == njs_vmcode_if_false_jump) { + cond_jump = (njs_vmcode_cond_jump_t *) p; + p += sizeof(njs_vmcode_cond_jump_t); + sign = (cond_jump->offset >= 0) ? "+" : ""; + + printf("JUMP IF FALSE %04lX %s%ld\n", + cond_jump->cond, sign, cond_jump->offset); + + continue; + } + + if (operation == njs_vmcode_jump) { + jump = (njs_vmcode_jump_t *) p; + p += sizeof(njs_vmcode_jump_t); + sign = (jump->offset >= 0) ? "+" : ""; + + printf("JUMP %s%ld\n", sign, jump->offset); + + continue; + } + + if (operation == njs_vmcode_method) { + method = (njs_vmcode_method_t *) p; + p += sizeof(njs_vmcode_method_t); + + printf("METHOD %04lX %04lX %04lX %d\n", method->function, + method->object, method->method, method->code.nargs); + + continue; + } + + if (operation == njs_vmcode_property_each_start) { + prop_start = (njs_vmcode_prop_start_t *) p; + p += sizeof(njs_vmcode_prop_start_t); + + printf("PROPERTY START %04lX %04lX +%ld\n", + prop_start->each, prop_start->object, prop_start->offset); + + continue; + } + + if (operation == njs_vmcode_property_each) { + each = (njs_vmcode_prop_each_t *) p; + p += sizeof(njs_vmcode_prop_each_t); + + printf("PROPERTY EACH %04lX %04lX %04lX %ld\n", + each->retval, each->object, each->each, each->offset); + + continue; + } + + if (operation == njs_vmcode_try_start) { + try_start = (njs_vmcode_try_start_t *) p; + p += sizeof(njs_vmcode_try_start_t); + + printf("TRY START %04lX +%ld\n", + try_start->value, try_start->offset); + + continue; + } + + if (operation == njs_vmcode_catch) { + catch = (njs_vmcode_catch_t *) p; + p += sizeof(njs_vmcode_catch_t); + + printf("CATCH %04lX +%ld\n", + catch->exception, catch->offset); + + continue; + } + + if (operation == njs_vmcode_try_end) { + try_end = (njs_vmcode_try_end_t *) p; + p += sizeof(njs_vmcode_try_end_t); + + printf("TRY END +%ld\n", try_end->offset); + + continue; + } + code_name = code_names; n = nxt_nitems(code_names); @@ -193,26 +296,26 @@ njs_disassembler(u_char *start, u_char *end, nxt_str_t *text) if (operation == code_name->operation) { name = &code_name->name; - if (code_name->size == sizeof(njs_vmcode_method_t)) { - method = (njs_vmcode_method_t *) p; - nxt_log_error(NXT_LOG_INFO, log, "%V %p %p %p %p", - name, method->function, method->object, - method->method, method->code.nargs); - - } else if (code_name->size == sizeof(njs_vmcode_3addr_t)) { + if (code_name->size == sizeof(njs_vmcode_3addr_t)) { code3 = (njs_vmcode_3addr_t *) p; - nxt_log_error(NXT_LOG_INFO, log, "%V %p %p %p", - name, code3->dst, code3->src1, code3->src2); + + printf("%*s %04lX %04lX %04lX\n", + (int) name->len, name->data, + code3->dst, code3->src1, code3->src2); } else if (code_name->size == sizeof(njs_vmcode_2addr_t)) { code2 = (njs_vmcode_2addr_t *) p; - nxt_log_error(NXT_LOG_INFO, log, "%V %p %p", - name, code2->dst, code2->src); + + printf("%*s %04lX %04lX\n", + (int) name->len, name->data, + code2->dst, code2->src); } else if (code_name->size == sizeof(njs_vmcode_1addr_t)) { code1 = (njs_vmcode_1addr_t *) p; - nxt_log_error(NXT_LOG_INFO, log, "%V %p", - name, code1->index); + + printf("%*s %04lX\n", + (int) name->len, name->data, + code1->index); } p += code_name->size; @@ -226,9 +329,8 @@ njs_disassembler(u_char *start, u_char *end, nxt_str_t *text) } while (n != 0); p += sizeof(njs_vmcode_operation_t); - name = &unknown; - nxt_log_error(NXT_LOG_INFO, log, "%V %p", name, operation); + printf("UNKNOWN %04lX\n", (uintptr_t) operation); next: diff --git a/njs/njs_function.c b/njs/njs_function.c index ed1c3279..c983e12f 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/njs/njs_generator.c b/njs/njs_generator.c index 73b02e95..b38f8260 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -1481,6 +1481,7 @@ njs_generate_scope(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node, nxt_uint_t n; njs_index_t index; njs_value_t *value; + njs_vm_code_t *code; njs_vmcode_stop_t *stop; p = nxt_mem_cache_alloc(vm->mem_cache_pool, parser->code_size); @@ -1542,9 +1543,21 @@ njs_generate_scope(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node, *value++ = njs_value_void; } - nxt_thread_log_debug("SCOPE CODE:"); + if (vm->code == NULL) { + vm->code = nxt_array_create(4, sizeof(njs_vm_code_t), + &njs_array_mem_proto, vm->mem_cache_pool); + if (nxt_slow_path(vm->code == NULL)) { + return NXT_ERROR; + } + } + + code = nxt_array_add(vm->code, &njs_array_mem_proto, vm->mem_cache_pool); + if (nxt_slow_path(code == NULL)) { + return NXT_ERROR; + } - njs_disassembler(parser->code_start, parser->code_last, NULL); + code->start = parser->code_start; + code->end = parser->code_last; return NXT_OK; } diff --git a/njs/njs_number.c b/njs/njs_number.c index 2a97fd4a..15d8bdb9 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/njs/njs_object.c b/njs/njs_object.c index 5f36fdd4..ffb0946d 100644 --- a/njs/njs_object.c +++ b/njs/njs_object.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/njs/njs_vm.h b/njs/njs_vm.h index 5bbe0acc..c638d33b 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -692,9 +692,17 @@ struct njs_vm_s { njs_vm_shared_t *shared; njs_parser_t *parser; njs_regexp_pattern_t *pattern; + + nxt_array_t *code; /* of njs_vm_code_t */ }; +typedef struct { + u_char *start; + u_char *end; +} njs_vm_code_t; + + struct njs_vm_shared_s { nxt_lvlhsh_t keywords_hash; nxt_lvlhsh_t values_hash; @@ -706,8 +714,6 @@ struct njs_vm_shared_s { nxt_int_t njs_vmcode_interpreter(njs_vm_t *vm); -void njs_disassembler(u_char *start, u_char *end, nxt_str_t *text); - void njs_value_retain(njs_value_t *value); void njs_value_release(njs_vm_t *vm, njs_value_t *value); diff --git a/njs/njscript.h b/njs/njscript.h index df75e40f..9a27af66 100644 --- a/njs/njscript.h +++ b/njs/njscript.h @@ -93,6 +93,8 @@ NXT_EXPORT void njs_vm_return(njs_vm_t *vm, njs_value_t *retval); NXT_EXPORT nxt_int_t njs_vm_retval(njs_vm_t *vm, nxt_str_t *retval); NXT_EXPORT nxt_int_t njs_vm_exception(njs_vm_t *vm, nxt_str_t *retval); +NXT_EXPORT void njs_disassembler(njs_vm_t *vm); + NXT_EXPORT njs_ret_t njs_string_create(njs_vm_t *vm, njs_value_t *value, u_char *start, size_t size, size_t length); NXT_EXPORT njs_ret_t njs_void_set(njs_value_t *value); diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 17621802..2267a443 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -3231,7 +3231,7 @@ static const nxt_mem_proto_t njs_mem_cache_pool_proto = { static nxt_int_t -njs_unit_test(void) +njs_unit_test(nxt_bool_t disassemble) { void *ext_object; u_char *start; @@ -3278,6 +3278,10 @@ njs_unit_test(void) ret = njs_vm_compile(vm, &start, start + njs_test[i].script.len); if (ret == NXT_OK) { + if (disassemble) { + njs_disassembler(vm); + } + nvm = njs_vm_clone(vm, NULL, &ext_object); if (nvm == NULL) { return NXT_ERROR; @@ -3421,10 +3425,12 @@ njs_unit_test_benchmark(nxt_str_t *script, nxt_str_t *result, const char *msg, int nxt_cdecl main(int argc, char **argv) { - nxt_str_t script = nxt_string("1"); - nxt_str_t result = nxt_string("1"); + nxt_bool_t disassemble; + + static nxt_str_t script = nxt_string("1"); + static nxt_str_t result = nxt_string("1"); - nxt_str_t fibo_number = nxt_string( + static nxt_str_t fibo_number = nxt_string( "function fibo(n) {" " if (n > 1)" " return fibo(n - 1) + fibo(n - 2)" @@ -3432,7 +3438,7 @@ main(int argc, char **argv) "}" "fibo(32)"); - nxt_str_t fibo_ascii = nxt_string( + static nxt_str_t fibo_ascii = nxt_string( "function fibo(n) {" " if (n > 1)" " return fibo(n - 1) + fibo(n - 2)" @@ -3440,7 +3446,7 @@ main(int argc, char **argv) "}" "fibo(32).length"); - nxt_str_t fibo_bytes = nxt_string( + static nxt_str_t fibo_bytes = nxt_string( "function fibo(n) {" " if (n > 1)" " return fibo(n - 1) + fibo(n - 2)" @@ -3448,7 +3454,7 @@ main(int argc, char **argv) "}" "fibo(32).length"); - nxt_str_t fibo_utf8 = nxt_string( + static nxt_str_t fibo_utf8 = nxt_string( "function fibo(n) {" " if (n > 1)" " return fibo(n - 1) + fibo(n - 2)" @@ -3456,9 +3462,11 @@ main(int argc, char **argv) "}" "fibo(32).length"); - nxt_str_t fibo_result = nxt_string("3524578"); + static nxt_str_t fibo_result = nxt_string("3524578"); + disassemble = 0; + if (argc > 1) { switch (argv[1][0]) { @@ -3482,10 +3490,14 @@ main(int argc, char **argv) return njs_unit_test_benchmark(&fibo_utf8, &fibo_result, "fibobench utf8 strings", 1); + case 'd': + disassemble = 1; + break; + default: break; } } - return njs_unit_test(); + return njs_unit_test(disassemble); }