From: Igor Sysoev Date: Mon, 25 Jan 2016 12:17:00 +0000 (+0300) Subject: An additional trap frame has been removed, the trap values are X-Git-Tag: 0.1.0~78 X-Git-Url: http://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=0b609f6c5ff4a11c527d3f43fdde604903dd4051;p=njs.git An additional trap frame has been removed, the trap values are stored just in native function frame. --- diff --git a/njs/njs_function.c b/njs/njs_function.c index 8eacc35a..e680d2c5 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -101,6 +101,7 @@ njs_function_frame_alloc(njs_vm_t *vm, size_t size) frame->ctor = 0; frame->reentrant = 0; + frame->trap_tries = 0; frame->trap_reference = 0; frame->exception.next = NULL; diff --git a/njs/njs_function.h b/njs/njs_function.h index 3dc32e6c..7f17fbc0 100644 --- a/njs/njs_function.h +++ b/njs/njs_function.h @@ -56,6 +56,10 @@ struct njs_exception_s { struct njs_native_frame_s { + njs_value_t trap_scratch; + njs_value_t trap_values[2]; + u_char *trap_restart; + u_char *free; /* @@ -65,7 +69,6 @@ struct njs_native_frame_s { union { njs_function_t *function; u_char *return_address; - u_char *restart; } u; njs_native_frame_t *previous; @@ -76,29 +79,29 @@ struct njs_native_frame_s { uint32_t free_size; /* Function is called as constructor with "new" keyword. */ - uint8_t ctor; /* 1 bit */ + uint8_t ctor; /* 1 bit */ /* * The first frame in chunk. * 7 bits are just to possibly initialize first and skip * fields with one operation. */ - uint8_t first:7; /* 1 bit */ + uint8_t first:7; /* 1 bit */ /* Skip the Function.call() and Function.apply() methods frames. */ - uint8_t skip:1; /* 1 bit */ + uint8_t skip:1; /* 1 bit */ - /* - * The function is reentrant. It is usually used as a flag, - * however, in traps it used to allow just two entrances. - */ - uint8_t reentrant:7; /* 2 bits */ + /* The function is reentrant. */ + uint8_t reentrant:1; /* 1 bit */ + + /* A number of trap tries, it can be no more than three. */ + uint8_t trap_tries:2; /* 2 bits */ /* * The first operand in trap is reference to original value, * it is used to increment or decrement this value. */ - uint8_t trap_reference:1; + uint8_t trap_reference:1; /* 1 bit */ }; diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 10efda32..80dbf791 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -84,7 +84,7 @@ static nxt_noinline nxt_bool_t njs_values_strict_equal(njs_value_t *val1, static nxt_noinline njs_ret_t njs_function_frame_free(njs_vm_t *vm, njs_native_frame_t *frame, njs_native_frame_t *skip); -static njs_ret_t njs_vm_trap(njs_vm_t *vm, nxt_uint_t trap, njs_value_t *value1, +static void njs_vm_trap(njs_vm_t *vm, nxt_uint_t trap, njs_value_t *value1, njs_value_t *value2); static njs_ret_t njs_vmcode_number_primitive(njs_vm_t *vm, njs_value_t *invld, njs_value_t *narg); @@ -220,14 +220,9 @@ njs_vmcode_interpreter(njs_vm_t *vm) case NJS_TRAP_INCDEC: case NJS_TRAP_PROPERTY: - ret = njs_vm_trap(vm, ret - NJS_TRAP_BASE, value1, value2); + njs_vm_trap(vm, ret - NJS_TRAP_BASE, value1, value2); - if (nxt_fast_path(ret == NXT_OK)) { - goto again; - } - - ret = NXT_ERROR; - break; + goto again; default: break; @@ -2553,47 +2548,31 @@ static const njs_vm_trap_t njs_vm_traps[] = { }; -static njs_ret_t +static void njs_vm_trap(njs_vm_t *vm, nxt_uint_t trap, njs_value_t *value1, njs_value_t *value2) { - size_t size; - njs_value_t *values; - njs_native_frame_t *frame; - - size = NJS_NATIVE_FRAME_SIZE + 3 * sizeof(njs_value_t); - - frame = njs_function_frame_alloc(vm, size); - if (nxt_slow_path(frame == NULL)) { - return NXT_ERROR; - } - /* - * The values[0] is scratch value for results of "valueOf" and - * "toString" methods. The values[1] and values[2] are original - * operand values which will be replaced with primitive values - * returned by "valueOf" or "toString" methods. The scratch value - * is stored separately to preserve the original operand values for - * the second method call if the first method call will return - * non-primitive value. + * The trap_scratch value is for results of "valueOf" and "toString" + * methods. The trap_values[] are original operand values which will + * be replaced with primitive values returned by "valueOf" or "toString" + * methods. The scratch value is stored separately to preserve the + * original operand values for the second method call if the first + * method call will return non-primitive value. */ - values = njs_native_data(frame); - njs_set_invalid(&values[0]); - values[2] = *value2; - - frame->trap_reference = njs_vm_traps[trap].reference_value; + njs_set_invalid(&vm->frame->trap_scratch); + vm->frame->trap_values[1] = *value2; + vm->frame->trap_reference = njs_vm_traps[trap].reference_value; if (njs_vm_traps[trap].reference_value) { - values[1].data.u.value = value1; + vm->frame->trap_values[0].data.u.value = value1; } else { - values[1] = *value1; + vm->frame->trap_values[0] = *value1; } - frame->u.restart = vm->current; + vm->frame->trap_restart = vm->current; vm->current = (u_char *) njs_vm_traps[trap].code; - - return NXT_OK; } @@ -2604,8 +2583,7 @@ njs_vmcode_number_primitive(njs_vm_t *vm, njs_value_t *invld, njs_value_t *narg) njs_ret_t ret; njs_value_t *value; - value = njs_native_data(vm->frame); - value = &value[(uintptr_t) narg + 1]; + value = &vm->frame->trap_values[(uintptr_t) narg]; ret = njs_primitive_value(vm, value, 0); @@ -2634,8 +2612,7 @@ njs_vmcode_string_primitive(njs_vm_t *vm, njs_value_t *invld, njs_value_t *narg) njs_ret_t ret; njs_value_t *value; - value = njs_native_data(vm->frame); - value = &value[(uintptr_t) narg + 1]; + value = &vm->frame->trap_values[(uintptr_t) narg]; ret = njs_primitive_value(vm, value, 1); @@ -2677,7 +2654,7 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) }; if (!njs_is_primitive(value)) { - retval = njs_native_data(vm->frame); + retval = &vm->frame->trap_scratch; if (!njs_is_primitive(retval)) { @@ -2685,8 +2662,8 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) vm->exception = &njs_exception_type_error; ret = NXT_ERROR; - if (njs_is_object(value) && vm->frame->reentrant < 2) { - hint ^= vm->frame->reentrant++; + if (njs_is_object(value) && vm->frame->trap_tries < 2) { + hint ^= vm->frame->trap_tries++; lhq.key_hash = hashes[hint]; lhq.key = names[hint]; @@ -2741,7 +2718,7 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint) njs_set_invalid(retval); } - vm->frame->reentrant = 0; + vm->frame->trap_tries = 0; return 1; } @@ -2752,26 +2729,20 @@ njs_vmcode_restart(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) { u_char *restart; njs_ret_t ret; - njs_value_t *retval, *values, *value1; - njs_native_frame_t *frame; + njs_value_t *retval, *value1; njs_vmcode_generic_t *vmcode; - frame = vm->frame; - vm->frame = frame->previous; - vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = frame->previous->arguments; - - restart = frame->u.restart; + restart = vm->frame->trap_restart; vm->current = restart; vmcode = (njs_vmcode_generic_t *) restart; - values = njs_native_data(frame); - value1 = &values[1]; + value1 = &vm->frame->trap_values[0]; - if (frame->trap_reference) { + if (vm->frame->trap_reference) { value1 = value1->data.u.value; } - ret = vmcode->code.operation(vm, value1, &values[2]); + ret = vmcode->code.operation(vm, value1, &vm->frame->trap_values[1]); retval = njs_vmcode_operand(vm, vmcode->operand1); @@ -2779,10 +2750,6 @@ njs_vmcode_restart(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) *retval = vm->retval; - if (frame->first) { - nxt_mem_cache_free(vm->mem_cache_pool, frame); - } - return ret; } @@ -2846,10 +2813,8 @@ fail: static njs_ret_t njs_object_value_to_string(njs_vm_t *vm, njs_value_t *value) { - size_t size; - njs_ret_t ret; - njs_value_t *retval; - njs_native_frame_t *frame; + u_char *current; + njs_ret_t ret; static const njs_vmcode_1addr_t value_to_string[] = { { .code = { .operation = njs_vmcode_value_to_string, @@ -2857,44 +2822,30 @@ njs_object_value_to_string(njs_vm_t *vm, njs_value_t *value) .retval = NJS_VMCODE_NO_RETVAL } }, }; - size = NJS_NATIVE_FRAME_SIZE + 2 * sizeof(njs_value_t); - - frame = njs_function_frame_alloc(vm, size); - if (nxt_slow_path(frame == NULL)) { - return NXT_ERROR; - } - /* - * Execute the single njs_vmcode_value_to_string() instruction. The - * retval[0] is scratch value for results of "toString" or "valueOf" - * methods. The retval[1] is an original object value which will be - * replaced with primitive value returned by "toString" or "valueOf" + * Execute the single njs_vmcode_value_to_string() instruction. + * The trap_scratch value is for results of "toString" or "valueOf" + * methods. The trap_values[0] is an original object value which will + * be replaced with primitive value returned by "toString" or "valueOf" * methods. The scratch value is stored separately to preserve the * original object value for the second "valueOf" method call if the * first "toString" method call will return non-primitive value. */ - frame->u.return_address = vm->current; + current = vm->current; vm->current = (u_char *) value_to_string; - retval = njs_native_data(vm->frame); - njs_set_invalid(&retval[0]); - retval[1] = *value; + njs_set_invalid(&vm->frame->trap_scratch); + vm->frame->trap_values[0] = *value; ret = njs_vmcode_interpreter(vm); if (ret == NJS_STOP) { ret = NXT_OK; - *value = retval[1]; + *value = vm->frame->trap_values[0]; } - vm->current = frame->u.return_address; - vm->frame = frame->previous; - vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = frame->previous->arguments; - - if (frame->first) { - nxt_mem_cache_free(vm->mem_cache_pool, frame); - } + vm->current = current; return ret; } @@ -2904,12 +2855,9 @@ static njs_ret_t njs_vmcode_value_to_string(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2) { - njs_ret_t ret; - njs_value_t *value; - - value = njs_native_data(vm->frame); + njs_ret_t ret; - ret = njs_primitive_value(vm, &value[1], 1); + ret = njs_primitive_value(vm, &vm->frame->trap_values[0], 1); if (nxt_fast_path(ret > 0)) { return NJS_STOP; diff --git a/njs/njscript.c b/njs/njscript.c index e2468b97..540caab1 100644 --- a/njs/njscript.c +++ b/njs/njscript.c @@ -290,6 +290,8 @@ njs_vm_clone(njs_vm_t *vm, nxt_mem_cache_pool_t *mcp, void **external) frame->native.arguments = NULL; frame->native.first = 1; frame->native.skip = 0; + frame->native.reentrant = 0; + frame->native.trap_tries = 0; frame->native.exception.next = NULL; frame->native.exception.catch = NULL;