[njs] Splitting vmcode functionality from njs_vm.c into njs_vmcode.c
Dmitry Volyntsev
xeioex at nginx.com
Tue Jul 23 17:02:48 UTC 2019
details: https://hg.nginx.org/njs/rev/7fd8df281a37
branches:
changeset: 1066:7fd8df281a37
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Jul 23 17:53:00 2019 +0300
description:
Splitting vmcode functionality from njs_vm.c into njs_vmcode.c
No functional changes.
diffstat:
auto/sources | 1 +
njs/njs_core.h | 1 +
njs/njs_vm.c | 2435 +-----------------------------------------------------
njs/njs_vm.h | 414 +---------
njs/njs_vmcode.c | 2385 ++++++++++++++++++++++++++++++++++++++++++++++++++++
njs/njs_vmcode.h | 443 +++++++++
6 files changed, 2832 insertions(+), 2847 deletions(-)
diffs (truncated from 5768 to 1000 lines):
diff -r 82c03a8af063 -r 7fd8df281a37 auto/sources
--- a/auto/sources Sat Jul 20 13:31:59 2019 +0300
+++ b/auto/sources Tue Jul 23 17:53:00 2019 +0300
@@ -32,6 +32,7 @@ NJS_LIB_SRCS=" \
njs/njs.c \
njs/njs_value.c \
njs/njs_vm.c \
+ njs/njs_vmcode.c \
njs/njs_boolean.c \
njs/njs_number.c \
njs/njs_string.c \
diff -r 82c03a8af063 -r 7fd8df281a37 njs/njs_core.h
--- a/njs/njs_core.h Sat Jul 20 13:31:59 2019 +0300
+++ b/njs/njs_core.h Tue Jul 23 17:53:00 2019 +0300
@@ -34,6 +34,7 @@
#include <njs.h>
#include <njs_value.h>
#include <njs_vm.h>
+#include <njs_vmcode.h>
#include <njs_variable.h>
#include <njs_lexer.h>
#include <njs_parser.h>
diff -r 82c03a8af063 -r 7fd8df281a37 njs/njs_vm.c
--- a/njs/njs_vm.c Sat Jul 20 13:31:59 2019 +0300
+++ b/njs/njs_vm.c Tue Jul 23 17:53:00 2019 +0300
@@ -9,33 +9,6 @@
#include <string.h>
-struct njs_property_next_s {
- uint32_t index;
- njs_array_t *array;
-};
-
-
-/*
- * These functions are forbidden to inline to minimize JavaScript VM
- * interpreter memory footprint. The size is less than 8K on AMD64
- * and should fit in CPU L1 instruction cache.
- */
-
-static njs_ret_t njs_string_concat(njs_vm_t *vm, njs_value_t *val1,
- njs_value_t *val2);
-static njs_ret_t njs_values_equal(njs_vm_t *vm, njs_value_t *val1,
- njs_value_t *val2);
-static njs_ret_t njs_primitive_values_compare(njs_vm_t *vm, njs_value_t *val1,
- njs_value_t *val2);
-static njs_ret_t njs_function_frame_create(njs_vm_t *vm, njs_value_t *value,
- const njs_value_t *this, uintptr_t nargs, nxt_bool_t ctor);
-static njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *value);
-
-static njs_ret_t njs_vm_add_backtrace_entry(njs_vm_t *vm, njs_frame_t *frame);
-
-void njs_debug(njs_index_t index, njs_value_t *value);
-
-
const nxt_str_t njs_entry_main = nxt_string("main");
const nxt_str_t njs_entry_module = nxt_string("module");
const nxt_str_t njs_entry_native = nxt_string("native");
@@ -43,2126 +16,6 @@ const nxt_str_t njs_entry_unknown =
const nxt_str_t njs_entry_anonymous = nxt_string("anonymous");
-/*
- * The nJSVM is optimized for an ABIs where the first several arguments
- * are passed in registers (AMD64, ARM32/64): two pointers to the operand
- * values is passed as arguments although they are not always used.
- */
-
-nxt_int_t
-njs_vmcode_interpreter(njs_vm_t *vm)
-{
- u_char *catch, call;
- njs_ret_t ret;
- njs_value_t *retval, *value1, *value2;
- njs_frame_t *frame;
- njs_native_frame_t *previous;
- njs_vmcode_generic_t *vmcode;
-
-start:
-
- for ( ;; ) {
-
- vmcode = (njs_vmcode_generic_t *) vm->current;
-
- /*
- * The first operand is passed as is in value2 to
- * njs_vmcode_jump(),
- * njs_vmcode_if_true_jump(),
- * njs_vmcode_if_false_jump(),
- * njs_vmcode_validate(),
- * njs_vmcode_function_frame(),
- * njs_vmcode_function_call(),
- * njs_vmcode_return(),
- * njs_vmcode_try_start(),
- * njs_vmcode_try_continue(),
- * njs_vmcode_try_break(),
- * njs_vmcode_try_end(),
- * njs_vmcode_catch().
- * njs_vmcode_throw().
- * njs_vmcode_stop().
- */
- value2 = (njs_value_t *) vmcode->operand1;
- value1 = NULL;
-
- switch (vmcode->code.operands) {
-
- case NJS_VMCODE_3OPERANDS:
- value2 = njs_vmcode_operand(vm, vmcode->operand3);
-
- /* Fall through. */
-
- case NJS_VMCODE_2OPERANDS:
- value1 = njs_vmcode_operand(vm, vmcode->operand2);
- }
-
- ret = vmcode->code.operation(vm, value1, value2);
-
- /*
- * On success an operation returns size of the bytecode,
- * a jump offset or zero after the call or return operations.
- * Jumps can return a negative offset. Compilers can generate
- * (ret < 0 && ret >= NJS_PREEMPT)
- * as a single unsigned comparision.
- */
-
- if (nxt_slow_path(ret < 0 && ret >= NJS_PREEMPT)) {
- break;
- }
-
- vm->current += ret;
-
- if (vmcode->code.retval) {
- retval = njs_vmcode_operand(vm, vmcode->operand1);
- njs_release(vm, retval);
- *retval = vm->retval;
- }
- }
-
- if (ret == NXT_ERROR) {
-
- for ( ;; ) {
- frame = (njs_frame_t *) vm->top_frame;
-
- call = frame->native.call;
- catch = frame->native.exception.catch;
-
- if (catch != NULL) {
- vm->current = catch;
-
- if (vm->debug != NULL) {
- nxt_array_reset(vm->backtrace);
- }
-
- goto start;
- }
-
- if (vm->debug != NULL
- && njs_vm_add_backtrace_entry(vm, frame) != NXT_OK)
- {
- return NXT_ERROR;
- }
-
- previous = frame->native.previous;
- if (previous == NULL) {
- return NXT_ERROR;
- }
-
- njs_vm_scopes_restore(vm, frame, previous);
-
- if (frame->native.size != 0) {
- vm->stack_size -= frame->native.size;
- nxt_mp_free(vm->mem_pool, frame);
- }
-
- if (call) {
- return NXT_ERROR;
- }
- }
- }
-
- /* NXT_ERROR, NJS_STOP. */
-
- return ret;
-}
-
-
-nxt_int_t
-njs_vmcode_run(njs_vm_t *vm)
-{
- njs_ret_t ret;
-
- vm->top_frame->call = 1;
-
- if (nxt_slow_path(vm->count > 128)) {
- njs_range_error(vm, "Maximum call stack size exceeded");
- return NXT_ERROR;
- }
-
- vm->count++;
-
- ret = njs_vmcode_interpreter(vm);
- if (ret == NJS_STOP) {
- ret = NJS_OK;
- }
-
- vm->count--;
-
- return ret;
-}
-
-
-njs_ret_t
-njs_vmcode_object(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
-{
- njs_object_t *object;
-
- object = njs_object_alloc(vm);
-
- if (nxt_fast_path(object != NULL)) {
- njs_set_object(&vm->retval, object);
-
- return sizeof(njs_vmcode_object_t);
- }
-
- return NXT_ERROR;
-}
-
-
-njs_ret_t
-njs_vmcode_array(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
-{
- uint32_t length;
- njs_array_t *array;
- njs_value_t *value;
- njs_vmcode_array_t *code;
-
- code = (njs_vmcode_array_t *) vm->current;
-
- array = njs_array_alloc(vm, code->length, NJS_ARRAY_SPARE);
-
- if (nxt_fast_path(array != NULL)) {
-
- if (code->code.ctor) {
- /* Array of the form [,,,], [1,,]. */
- value = array->start;
- length = array->length;
-
- do {
- njs_set_invalid(value);
- value++;
- length--;
- } while (length != 0);
-
- } else {
- /* Array of the form [], [,,1], [1,2,3]. */
- array->length = 0;
- }
-
- njs_set_array(&vm->retval, array);
-
- return sizeof(njs_vmcode_array_t);
- }
-
- return NXT_ERROR;
-}
-
-
-njs_ret_t
-njs_vmcode_function(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
-{
- njs_function_t *function;
- njs_function_lambda_t *lambda;
- njs_vmcode_function_t *code;
-
- code = (njs_vmcode_function_t *) vm->current;
- lambda = code->lambda;
-
- function = njs_function_alloc(vm, lambda, vm->active_frame->closures, 0);
- if (nxt_slow_path(function == NULL)) {
- return NXT_ERROR;
- }
-
- njs_set_function(&vm->retval, function);
-
- return sizeof(njs_vmcode_function_t);
-}
-
-
-njs_ret_t
-njs_vmcode_this(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
-{
- njs_frame_t *frame;
- njs_value_t *value;
- njs_vmcode_this_t *code;
-
- frame = (njs_frame_t *) vm->active_frame;
- code = (njs_vmcode_this_t *) vm->current;
-
- value = njs_vmcode_operand(vm, code->dst);
- *value = frame->native.arguments[0];
-
- return sizeof(njs_vmcode_this_t);
-}
-
-
-njs_ret_t
-njs_vmcode_arguments(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
-{
- nxt_int_t ret;
- njs_frame_t *frame;
- njs_value_t *value;
- njs_vmcode_arguments_t *code;
-
- frame = (njs_frame_t *) vm->active_frame;
-
- if (frame->native.arguments_object == NULL) {
- ret = njs_function_arguments_object_init(vm, &frame->native);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NXT_ERROR;
- }
- }
-
- code = (njs_vmcode_arguments_t *) vm->current;
-
- value = njs_vmcode_operand(vm, code->dst);
- njs_set_object(value, frame->native.arguments_object);
-
- return sizeof(njs_vmcode_arguments_t);
-}
-
-
-njs_ret_t
-njs_vmcode_regexp(njs_vm_t *vm, njs_value_t *invld1, njs_value_t *invld2)
-{
- njs_regexp_t *regexp;
- njs_vmcode_regexp_t *code;
-
- code = (njs_vmcode_regexp_t *) vm->current;
-
- regexp = njs_regexp_alloc(vm, code->pattern);
-
- if (nxt_fast_path(regexp != NULL)) {
- njs_set_regexp(&vm->retval, regexp);
-
- return sizeof(njs_vmcode_regexp_t);
- }
-
- return NXT_ERROR;
-}
-
-
-njs_ret_t
-njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *invld1,
- njs_value_t *retval)
-{
- nxt_int_t ret;
- njs_array_t *array;
- njs_value_t *value;
-
- static const njs_function_t concat = {
- .native = 1,
- .args_offset = 1,
- .u.native = njs_string_prototype_concat
- };
-
- value = njs_vmcode_operand(vm, retval);
-
- if (!njs_is_primitive(value)) {
- array = njs_array(value);
-
- ret = njs_function_frame(vm, (njs_function_t *) &concat,
- (njs_value_t *) &njs_string_empty,
- array->start, array->length, 0);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- ret = njs_function_frame_invoke(vm, (njs_index_t) retval);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
- }
-
- return sizeof(njs_vmcode_template_literal_t);
-}
-
-
-njs_ret_t
-njs_vmcode_object_copy(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld)
-{
- njs_object_t *object;
- njs_function_t *function;
-
- switch (value->type) {
-
- case NJS_OBJECT:
- object = njs_object_value_copy(vm, value);
- if (nxt_slow_path(object == NULL)) {
- return NXT_ERROR;
- }
-
- break;
-
- case NJS_FUNCTION:
- function = njs_function_value_copy(vm, value);
- if (nxt_slow_path(function == NULL)) {
- return NXT_ERROR;
- }
-
- break;
-
- default:
- break;
- }
-
- vm->retval = *value;
-
- njs_retain(value);
-
- return sizeof(njs_vmcode_object_copy_t);
-}
-
-
-njs_ret_t
-njs_vmcode_property_get(njs_vm_t *vm, njs_value_t *object,
- njs_value_t *property)
-{
- njs_ret_t ret;
- njs_value_t *retval;
- njs_vmcode_prop_get_t *code;
-
- code = (njs_vmcode_prop_get_t *) vm->current;
- retval = njs_vmcode_operand(vm, code->value);
-
- ret = njs_value_property(vm, object, property, retval);
- if (nxt_slow_path(ret == NXT_ERROR)) {
- return ret;
- }
-
- vm->retval = *retval;
-
- return sizeof(njs_vmcode_prop_get_t);
-}
-
-
-njs_ret_t
-njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *object,
- njs_value_t *property)
-{
- uint32_t index, size;
- njs_ret_t ret;
- njs_array_t *array;
- njs_value_t *init, *value, name;
- njs_object_t *obj;
- njs_object_prop_t *prop;
- nxt_lvlhsh_query_t lhq;
- njs_vmcode_prop_set_t *code;
-
- code = (njs_vmcode_prop_set_t *) vm->current;
- init = njs_vmcode_operand(vm, code->value);
-
- switch (object->type) {
- case NJS_ARRAY:
- index = njs_value_to_index(property);
- if (nxt_slow_path(index == NJS_ARRAY_INVALID_INDEX)) {
- njs_internal_error(vm,
- "invalid index while property initialization");
- return NXT_ERROR;
- }
-
- array = object->data.u.array;
-
- if (index >= array->length) {
- size = index - array->length;
-
- ret = njs_array_expand(vm, array, 0, size + 1);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- value = &array->start[array->length];
-
- while (size != 0) {
- njs_set_invalid(value);
- value++;
- size--;
- }
-
- array->length = index + 1;
- }
-
- /* GC: retain. */
- array->start[index] = *init;
-
- break;
-
- case NJS_OBJECT:
- ret = njs_value_to_string(vm, &name, property);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NXT_ERROR;
- }
-
- njs_string_get(&name, &lhq.key);
- lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length);
- lhq.proto = &njs_object_hash_proto;
- lhq.pool = vm->mem_pool;
-
- obj = njs_object(object);
-
- ret = nxt_lvlhsh_find(&obj->__proto__->shared_hash, &lhq);
- if (ret == NXT_OK) {
- prop = lhq.value;
-
- if (prop->type == NJS_PROPERTY_HANDLER) {
- ret = prop->value.data.u.prop_handler(vm, object, init,
- &vm->retval);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- break;
- }
- }
-
- prop = njs_object_prop_alloc(vm, &name, init, 1);
- if (nxt_slow_path(prop == NULL)) {
- return NXT_ERROR;
- }
-
- lhq.value = prop;
- lhq.replace = 1;
-
- ret = nxt_lvlhsh_insert(&obj->hash, &lhq);
- if (nxt_slow_path(ret != NXT_OK)) {
- njs_internal_error(vm, "lvlhsh insert/replace failed");
- return NXT_ERROR;
- }
-
- break;
-
- default:
- njs_internal_error(vm, "unexpected object type \"%s\" "
- "while property initialization",
- njs_type_string(object->type));
-
- return NXT_ERROR;
- }
-
- return sizeof(njs_vmcode_prop_set_t);
-}
-
-
-njs_ret_t
-njs_vmcode_property_set(njs_vm_t *vm, njs_value_t *object,
- njs_value_t *property)
-{
- njs_ret_t ret;
- njs_value_t *value;
- njs_vmcode_prop_set_t *code;
-
- code = (njs_vmcode_prop_set_t *) vm->current;
- value = njs_vmcode_operand(vm, code->value);
-
- ret = njs_value_property_set(vm, object, property, value);
- if (nxt_slow_path(ret == NXT_ERROR)) {
- return ret;
- }
-
- return sizeof(njs_vmcode_prop_set_t);
-}
-
-
-njs_ret_t
-njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *object, njs_value_t *property)
-{
- njs_ret_t ret;
- njs_object_prop_t *prop;
- const njs_value_t *retval;
- njs_property_query_t pq;
-
- retval = &njs_value_false;
-
- njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);
-
- ret = njs_property_query(vm, &pq, object, property);
-
- switch (ret) {
-
- case NXT_OK:
- prop = pq.lhq.value;
-
- if (!njs_is_valid(&prop->value)) {
- break;
- }
-
- retval = &njs_value_true;
- break;
-
- case NXT_DECLINED:
- if (!njs_is_object(object) && !njs_is_external(object)) {
- njs_type_error(vm, "property in on a primitive value");
-
- return NXT_ERROR;
- }
-
- break;
-
- case NXT_ERROR:
- default:
-
- return ret;
- }
-
- vm->retval = *retval;
-
- return sizeof(njs_vmcode_3addr_t);
-}
-
-
-njs_ret_t
-njs_vmcode_property_delete(njs_vm_t *vm, njs_value_t *object,
- njs_value_t *property)
-{
- njs_ret_t ret;
- njs_object_prop_t *prop, *whipeout;
- njs_property_query_t pq;
-
- njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1);
-
- ret = njs_property_query(vm, &pq, object, property);
-
- switch (ret) {
-
- case NXT_OK:
- prop = pq.lhq.value;
-
- if (nxt_slow_path(!prop->configurable)) {
- njs_type_error(vm, "Cannot delete property \"%V\" of %s",
- &pq.lhq.key, njs_type_string(object->type));
- return NXT_ERROR;
- }
-
- if (nxt_slow_path(pq.shared)) {
- whipeout = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
- sizeof(njs_object_prop_t));
- if (nxt_slow_path(whipeout == NULL)) {
- njs_memory_error(vm);
- return NXT_ERROR;
- }
-
- njs_set_invalid(&whipeout->value);
- whipeout->name = prop->name;
- whipeout->type = NJS_WHITEOUT;
-
- pq.lhq.replace = 0;
- pq.lhq.value = whipeout;
- pq.lhq.pool = vm->mem_pool;
-
- ret = nxt_lvlhsh_insert(&pq.prototype->hash, &pq.lhq);
- if (nxt_slow_path(ret != NXT_OK)) {
- njs_internal_error(vm, "lvlhsh insert failed");
- return NXT_ERROR;
- }
-
- break;
- }
-
- switch (prop->type) {
- case NJS_PROPERTY:
- case NJS_METHOD:
- break;
-
- case NJS_PROPERTY_REF:
- njs_set_invalid(prop->value.data.u.value);
- goto done;
-
- case NJS_PROPERTY_HANDLER:
- ret = prop->value.data.u.prop_handler(vm, object, NULL, NULL);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- goto done;
-
- default:
- njs_internal_error(vm, "unexpected property type \"%s\" "
- "while deleting",
- njs_prop_type_string(prop->type));
-
- return NXT_ERROR;
- }
-
- /* GC: release value. */
- prop->type = NJS_WHITEOUT;
- njs_set_invalid(&prop->value);
-
- break;
-
- case NXT_DECLINED:
- break;
-
- case NXT_ERROR:
- default:
-
- return ret;
- }
-
-done:
-
- vm->retval = njs_value_true;
-
- return sizeof(njs_vmcode_3addr_t);
-}
-
-
-njs_ret_t
-njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object,
- njs_value_t *invld)
-{
- void *obj;
- njs_ret_t ret;
- njs_property_next_t *next;
- const njs_extern_t *ext_proto;
- njs_vmcode_prop_foreach_t *code;
-
- if (njs_is_external(object)) {
- ext_proto = object->external.proto;
-
- if (ext_proto->foreach != NULL) {
- obj = njs_extern_object(vm, object);
-
- ret = ext_proto->foreach(vm, obj, &vm->retval);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
- }
-
- goto done;
- }
-
- next = nxt_mp_alloc(vm->mem_pool, sizeof(njs_property_next_t));
- if (nxt_slow_path(next == NULL)) {
- njs_memory_error(vm);
- return NXT_ERROR;
- }
-
- next->index = 0;
- next->array = njs_value_enumerate(vm, object, NJS_ENUM_KEYS, 0);
- if (nxt_slow_path(next->array == NULL)) {
- njs_memory_error(vm);
- return NXT_ERROR;
- }
-
- vm->retval.data.u.next = next;
-
-done:
-
- code = (njs_vmcode_prop_foreach_t *) vm->current;
-
- return code->offset;
-}
-
-
-njs_ret_t
-njs_vmcode_property_next(njs_vm_t *vm, njs_value_t *object, njs_value_t *value)
-{
- void *obj;
- njs_ret_t ret;
- njs_value_t *retval;
- njs_property_next_t *next;
- const njs_extern_t *ext_proto;
- njs_vmcode_prop_next_t *code;
-
- code = (njs_vmcode_prop_next_t *) vm->current;
- retval = njs_vmcode_operand(vm, code->retval);
-
- if (njs_is_external(object)) {
- ext_proto = object->external.proto;
-
- if (ext_proto->next != NULL) {
- obj = njs_extern_object(vm, object);
-
- ret = ext_proto->next(vm, retval, obj, value);
-
- if (ret == NXT_OK) {
- return code->offset;
- }
-
- if (nxt_slow_path(ret == NXT_ERROR)) {
- return ret;
- }
-
- /* ret == NJS_DONE. */
- }
-
- return sizeof(njs_vmcode_prop_next_t);
- }
-
- next = value->data.u.next;
-
- if (next->index < next->array->length) {
- *retval = next->array->data[next->index++];
-
- return code->offset;
- }
-
- nxt_mp_free(vm->mem_pool, next);
-
- return sizeof(njs_vmcode_prop_next_t);
-}
-
-
-njs_ret_t
-njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object,
- njs_value_t *constructor)
-{
- nxt_int_t ret;
- njs_value_t value;
- njs_object_t *prototype, *proto;
- const njs_value_t *retval;
-
- static njs_value_t prototype_string = njs_string("prototype");
-
- if (!njs_is_function(constructor)) {
- njs_type_error(vm, "right argument is not a function");
- return NXT_ERROR;
- }
-
- retval = &njs_value_false;
-
- if (njs_is_object(object)) {
- value = njs_value_undefined;
- ret = njs_value_property(vm, constructor, &prototype_string, &value);
-
- if (nxt_slow_path(ret == NXT_ERROR)) {
- return ret;
- }
-
- if (nxt_fast_path(ret == NXT_OK)) {
-
- if (nxt_slow_path(!njs_is_object(&value))) {
- njs_internal_error(vm, "prototype is not an object");
- return NXT_ERROR;
- }
-
- prototype = njs_object(&value);
- proto = njs_object(object);
-
- do {
- proto = proto->__proto__;
-
- if (proto == prototype) {
- retval = &njs_value_true;
- break;
- }
-
- } while (proto != NULL);
- }
- }
-
- vm->retval = *retval;
-
- return sizeof(njs_vmcode_instance_of_t);
-}
-
-
-njs_ret_t
-njs_vmcode_increment(njs_vm_t *vm, njs_value_t *reference, njs_value_t *value)
-{
- double num;
- njs_ret_t ret;
- njs_value_t numeric;
-
- if (nxt_slow_path(!njs_is_numeric(value))) {
- ret = njs_value_to_numeric(vm, &numeric, value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- num = njs_number(&numeric);
-
- } else {
- num = njs_number(value);
- }
-
- njs_release(vm, reference);
-
- njs_set_number(reference, num + 1.0);
- vm->retval = *reference;
-
- return sizeof(njs_vmcode_3addr_t);
-}
-
-
-njs_ret_t
-njs_vmcode_decrement(njs_vm_t *vm, njs_value_t *reference, njs_value_t *value)
-{
- double num;
- njs_ret_t ret;
- njs_value_t numeric;
-
- if (nxt_slow_path(!njs_is_numeric(value))) {
- ret = njs_value_to_numeric(vm, &numeric, value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- num = njs_number(&numeric);
-
- } else {
- num = njs_number(value);
- }
-
- njs_release(vm, reference);
-
- njs_set_number(reference, num - 1.0);
- vm->retval = *reference;
-
- return sizeof(njs_vmcode_3addr_t);
-}
-
-
-njs_ret_t
-njs_vmcode_post_increment(njs_vm_t *vm, njs_value_t *reference,
- njs_value_t *value)
-{
- double num;
- njs_ret_t ret;
- njs_value_t numeric;
-
- if (nxt_slow_path(!njs_is_numeric(value))) {
- ret = njs_value_to_numeric(vm, &numeric, value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- num = njs_number(&numeric);
-
- } else {
- num = njs_number(value);
- }
-
- njs_release(vm, reference);
-
- njs_set_number(reference, num + 1.0);
- njs_set_number(&vm->retval, num);
-
- return sizeof(njs_vmcode_3addr_t);
-}
-
-
-njs_ret_t
-njs_vmcode_post_decrement(njs_vm_t *vm, njs_value_t *reference,
- njs_value_t *value)
-{
- double num;
- njs_ret_t ret;
- njs_value_t numeric;
-
- if (nxt_slow_path(!njs_is_numeric(value))) {
- ret = njs_value_to_numeric(vm, &numeric, value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return ret;
- }
-
- num = njs_number(&numeric);
-
- } else {
- num = njs_number(value);
- }
-
- njs_release(vm, reference);
-
- njs_set_number(reference, num - 1.0);
- njs_set_number(&vm->retval, num);
-
- return sizeof(njs_vmcode_3addr_t);
-}
-
-
-njs_ret_t
-njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *invld)
-{
- /* ECMAScript 5.1: null, array and regexp are objects. */
-
- static const njs_value_t *types[NJS_TYPE_MAX] = {
- &njs_string_object,
- &njs_string_undefined,
- &njs_string_boolean,
- &njs_string_number,
- &njs_string_string,
- &njs_string_data,
- &njs_string_external,
- &njs_string_invalid,
- &njs_string_undefined,
- &njs_string_undefined,
- &njs_string_undefined,
- &njs_string_undefined,
- &njs_string_undefined,
More information about the nginx-devel
mailing list