]> git.kaiwu.me - njs.git/commitdiff
The "this" has been removed from njs_param_t.
authorIgor Sysoev <igor@sysoev.ru>
Fri, 12 Feb 2016 10:40:36 +0000 (13:40 +0300)
committerIgor Sysoev <igor@sysoev.ru>
Fri, 12 Feb 2016 10:40:36 +0000 (13:40 +0300)
12 files changed:
nginx/ngx_http_js_module.c
njs/njs_array.c
njs/njs_boolean.c
njs/njs_function.c
njs/njs_function.h
njs/njs_number.c
njs/njs_object.c
njs/njs_regexp.c
njs/njs_string.c
njs/njs_vm.c
njs/njscript.h
njs/test/njs_unit_test.c

index 591c20ad10362003db046ca1750ac80ecc39ffd7..b697ee22814f5808ece80d273e4d882e69163c68 100644 (file)
@@ -791,7 +791,7 @@ ngx_http_js_ext_send_header(njs_vm_t *vm, njs_param_t *param)
 {
     ngx_http_request_t  *r;
 
-    r = njs_value_data(param->this);
+    r = njs_value_data(njs_argument(param->args, 0));
 
     if (ngx_http_send_header(r) == NGX_ERROR) {
         return NJS_ERROR;
@@ -813,7 +813,7 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_param_t *param)
     ngx_chain_t         *out, *cl, **ll;
     ngx_http_request_t  *r;
 
-    r = njs_value_data(param->this);
+    r = njs_value_data(njs_argument(param->args, 0));
 
     out = NULL;
     ll = &out;
@@ -821,7 +821,7 @@ ngx_http_js_ext_send(njs_vm_t *vm, njs_param_t *param)
     args = param->args;
     nargs = param->nargs;
 
-    for (n = 0; n < nargs; n++) {
+    for (n = 1; n < nargs; n++) {
         next = 0;
 
         for ( ;; ) {
@@ -878,7 +878,7 @@ ngx_http_js_ext_finish(njs_vm_t *vm, njs_param_t *param)
 {
     ngx_http_request_t  *r;
 
-    r = njs_value_data(param->this);
+    r = njs_value_data(njs_argument(param->args, 0));
 
     if (ngx_http_send_special(r, NGX_HTTP_LAST) == NGX_ERROR) {
         return NJS_ERROR;
index 02507abb880d8750602449cb5530b724244676de..eda8af3c96f1e0f78341b0988343be660fbe639b 100644 (file)
@@ -181,8 +181,8 @@ njs_array_constructor(njs_vm_t *vm, njs_param_t *param)
     njs_value_t  *value, *args;
     njs_array_t  *array;
 
-    args = param->args;
-    size = param->nargs;
+    args = &param->args[1];
+    size = param->nargs - 1;
 
     if (size == 1 && njs_is_number(&args[0])) {
         num = args[0].data.u.number;
@@ -282,18 +282,18 @@ njs_array_prototype_slice(njs_vm_t *vm, njs_param_t *param)
     uint32_t     n;
     uintptr_t    nargs;
     njs_array_t  *array;
-    njs_value_t  *this, *value;
+    njs_value_t  *args, *value;
 
     start = 0;
     length = 0;
-    this = param->this;
+    args = param->args;
 
-    if (njs_is_array(this)) {
-        length = this->data.u.array->length;
+    if (njs_is_array(&args[0])) {
+        length = args[0].data.u.array->length;
         nargs = param->nargs;
 
-        if (nargs != 0) {
-            start = param->args[0].data.u.number;
+        if (nargs > 1) {
+            start = args[1].data.u.number;
 
             if (start < 0) {
                 start += length;
@@ -305,8 +305,8 @@ njs_array_prototype_slice(njs_vm_t *vm, njs_param_t *param)
 
             end = length;
 
-            if (nargs > 1) {
-                end = param->args[1].data.u.number;
+            if (nargs > 2) {
+                end = args[2].data.u.number;
 
                 if (end < 0) {
                     end += length;
@@ -332,7 +332,7 @@ njs_array_prototype_slice(njs_vm_t *vm, njs_param_t *param)
     vm->retval.data.truth = 1;
 
     if (length != 0) {
-        value = this->data.u.array->start;
+        value = args[0].data.u.array->start;
         n = 0;
 
         do {
@@ -351,14 +351,12 @@ njs_array_prototype_push(njs_vm_t *vm, njs_param_t *param)
 {
     uintptr_t    i, nargs;
     njs_ret_t    ret;
-    njs_value_t  *this, *args;
+    njs_value_t  *args;
     njs_array_t  *array;
 
-    this = param->this;
-
-    if (njs_is_array(this)) {
-        array = this->data.u.array;
-        nargs = param->nargs;
+    if (njs_is_array(&param->args[0])) {
+        array = param->args[0].data.u.array;
+        nargs = param->nargs - 1;
 
         if (nargs != 0) {
             if (nargs > array->size - array->length) {
@@ -369,8 +367,9 @@ njs_array_prototype_push(njs_vm_t *vm, njs_param_t *param)
             }
 
             args = param->args;
+            nargs = param->nargs;
 
-            for (i = 0; i < nargs; i++) {
+            for (i = 1; i < nargs; i++) {
                 /* GC: njs_retain(&args[i]); */
                 array->start[array->length++] = args[i];
             }
@@ -387,15 +386,12 @@ static njs_ret_t
 njs_array_prototype_pop(njs_vm_t *vm, njs_param_t *param)
 {
     njs_array_t        *array;
-    njs_value_t        *this;
     const njs_value_t  *retval, *value;
 
     retval = &njs_value_void;
 
-    this = param->this;
-
-    if (njs_is_array(this)) {
-        array = this->data.u.array;
+    if (njs_is_array(&param->args[0])) {
+        array = param->args[0].data.u.array;
 
         if (array->length != 0) {
             array->length--;
@@ -416,34 +412,33 @@ njs_array_prototype_pop(njs_vm_t *vm, njs_param_t *param)
 static njs_ret_t
 njs_array_prototype_unshift(njs_vm_t *vm, njs_param_t *param)
 {
-    uintptr_t    nargs;
+    uintptr_t    n;
     njs_ret_t    ret;
-    njs_value_t  *this, *args;
+    njs_value_t  *args;
     njs_array_t  *array;
 
-    this = param->this;
+    if (njs_is_array(&param->args[0])) {
+        array = param->args[0].data.u.array;
+        n = param->nargs - 1;
 
-    if (njs_is_array(this)) {
-        array = this->data.u.array;
-        nargs = param->nargs;
-
-        if (nargs != 0) {
-            if ((intptr_t) nargs > (array->start - array->data)) {
-                ret = njs_array_realloc(vm, array, nargs, array->size);
+        if (n != 0) {
+            if ((intptr_t) n > (array->start - array->data)) {
+                ret = njs_array_realloc(vm, array, n, array->size);
                 if (nxt_slow_path(ret != NXT_OK)) {
                     return ret;
                 }
             }
 
-            array->length += nargs;
+            array->length += n;
             args = param->args;
+            n = param->nargs;
 
             do {
-                nargs--;
-                /* GC: njs_retain(&args[nargs]); */
+                n--;
+                /* GC: njs_retain(&args[n]); */
                 array->start--;
-                array->start[0] = args[nargs];
-            } while (nargs != 0);
+                array->start[0] = args[n];
+            } while (n > 1);
         }
 
         njs_number_set(&vm->retval, array->length);
@@ -457,15 +452,12 @@ static njs_ret_t
 njs_array_prototype_shift(njs_vm_t *vm, njs_param_t *param)
 {
     njs_array_t        *array;
-    njs_value_t        *this;
     const njs_value_t  *retval, *value;
 
     retval = &njs_value_void;
 
-    this = param->this;
-
-    if (njs_is_array(this)) {
-        array = this->data.u.array;
+    if (njs_is_array(&param->args[0])) {
+        array = param->args[0].data.u.array;
 
         if (array->length != 0) {
             array->length--;
@@ -493,21 +485,31 @@ njs_array_prototype_shift(njs_vm_t *vm, njs_param_t *param)
 static njs_ret_t
 njs_array_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
 {
-    njs_value_t         *this;
+    njs_value_t         *this, *args;
     njs_object_prop_t   *prop;
     nxt_lvlhsh_query_t  lhq;
 
-    this = param->this;
+    args = param->args;
 
-    if (njs_is_object(this)) {
+    if (njs_is_object(&args[0])) {
         lhq.key_hash = NJS_JOIN_HASH;
         lhq.key.len = sizeof("join") - 1;
         lhq.key.data = (u_char *) "join";
 
-        prop = njs_object_property(vm, this->data.u.object, &lhq);
+        prop = njs_object_property(vm, args[0].data.u.object, &lhq);
 
         if (nxt_fast_path(prop != NULL && njs_is_function(&prop->value))) {
-            return njs_function_apply(vm, prop->value.data.u.function, param);
+
+            this = &args[0];
+
+            if (prop->value.data.u.function->native) {
+                param->args = &args[0];
+                param->nargs++;
+                this = NULL;
+            }
+
+            return njs_function_apply(vm, prop->value.data.u.function, this,
+                                      param);
         }
     }
 
@@ -521,16 +523,14 @@ njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param)
     uint32_t          max;
     nxt_uint_t        i, n;
     njs_array_t       *array;
-    njs_value_t       *this, *value, *values;
+    njs_value_t       *value, *values;
     njs_array_join_t  *join;
 
-    this = param->this;
-
-    if (!njs_is_array(this)) {
+    if (!njs_is_array(&param->args[0])) {
         goto empty;
     }
 
-    array = this->data.u.array;
+    array = param->args[0].data.u.array;
 
     if (array->length == 0) {
         goto empty;
@@ -559,7 +559,6 @@ njs_array_prototype_join(njs_vm_t *vm, njs_param_t *param)
         }
 
         join->continuation.function = njs_array_prototype_join_continuation;
-        join->continuation.this = this;
         join->continuation.args = param->args;
         join->continuation.nargs = param->nargs;
         join->values = values;
@@ -618,7 +617,7 @@ njs_array_prototype_join_continuation(njs_vm_t *vm, njs_param_t *param)
     n = 0;
     mask = -1;
 
-    array = param->this->data.u.array;
+    array = param->args[0].data.u.array;
 
     for (i = 0; i < array->length; i++) {
         value = &array->start[i];
@@ -646,8 +645,8 @@ njs_array_prototype_join_continuation(njs_vm_t *vm, njs_param_t *param)
         }
     }
 
-    if (param->nargs != 0) {
-        value = &param->args[0];
+    if (param->nargs > 1) {
+        value = &param->args[1];
 
     } else {
         value = (njs_value_t *) &njs_string_comma;
@@ -705,20 +704,12 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_param_t *param)
     size_t       length;
     uintptr_t    nargs;
     nxt_uint_t   i;
-    njs_value_t  *this, *args, *value;
+    njs_value_t  *args, *value;
     njs_array_t  *array;
 
-    this = param->this;
-
-    if (njs_is_array(this)) {
-        length = this->data.u.array->length;
-
-    } else {
-        length = 1;
-    }
-
-    nargs = param->nargs;
+    length = 0;
     args = param->args;
+    nargs = param->nargs;
 
     for (i = 0; i < nargs; i++) {
         if (njs_is_array(&args[i])) {
@@ -738,7 +729,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_param_t *param)
     vm->retval.type = NJS_ARRAY;
     vm->retval.data.truth = 1;
 
-    value = njs_array_copy(array->start, this);
+    value = array->start;
 
     for (i = 0; i < nargs; i++) {
         value = njs_array_copy(value, &args[i]);
@@ -774,13 +765,12 @@ static njs_ret_t
 njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param)
 {
     nxt_int_t         n, ret;
-    uintptr_t         nargs;
     njs_param_t       p;
     njs_array_t       *array;
     njs_value_t       *this, *args, arguments[3];
     njs_array_next_t  *next;
 
-    this = param->this;
+    args = param->args;
 
     if (!vm->frame->reentrant) {
         vm->frame->reentrant = 1;
@@ -790,7 +780,7 @@ njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param)
             return ret;
         }
 
-        array = this->data.u.array;
+        array = args[0].data.u.array;
         n = njs_array_next(array->start, 0, array->length);
 
         if (n < 0) {
@@ -807,10 +797,10 @@ njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param)
     n = next->index;
 
     /* GC: array elt, array */
-    array = this->data.u.array;
+    array = args[0].data.u.array;
     arguments[0] = array->start[n];
     njs_number_set(&arguments[1], n);
-    arguments[2] = *this;
+    arguments[2] = args[0];
 
     n = njs_array_next(array->start, ++n, next->length);
     next->index = n;
@@ -819,29 +809,25 @@ njs_array_prototype_for_each(njs_vm_t *vm, njs_param_t *param)
         vm->current += sizeof(njs_vmcode_function_call_t);
     }
 
-    nargs = param->nargs;
-    args = param->args;
-
-    p.this = (nargs > 1) ? &args[1] : (njs_value_t *) &njs_value_void;
+    this = (param->nargs > 2) ? &args[2] : (njs_value_t *) &njs_value_void;
     p.args = arguments;
     p.nargs = 3;
     p.retval = (njs_index_t) &next->retval;
 
-    return njs_function_apply(vm, args[0].data.u.function, &p);
+    return njs_function_apply(vm, args[1].data.u.function, this, &p);
 }
 
 
 static njs_ret_t
 njs_array_prototype_some(njs_vm_t *vm, njs_param_t *param)
 {
-    uintptr_t         nargs;
     nxt_int_t         n, ret;
     njs_param_t       p;
     njs_array_t       *array;
     njs_value_t       *this, *args, arguments[3];
     njs_array_next_t  *next;
 
-    this = param->this;
+    args = param->args;
 
     if (!vm->frame->reentrant) {
         vm->frame->reentrant = 1;
@@ -851,7 +837,7 @@ njs_array_prototype_some(njs_vm_t *vm, njs_param_t *param)
             return ret;
         }
 
-        array = this->data.u.array;
+        array = args[0].data.u.array;
         n = njs_array_next(array->start, 0, array->length);
         next = njs_native_data(vm->frame);
         next->index = n;
@@ -874,36 +860,32 @@ njs_array_prototype_some(njs_vm_t *vm, njs_param_t *param)
     }
 
     /* GC: array elt, array */
-    array = this->data.u.array;
+    array = args[0].data.u.array;
     arguments[0] = array->start[n];
     njs_number_set(&arguments[1], n);
-    arguments[2] = *this;
+    arguments[2] = args[0];
 
     next->index = njs_array_next(array->start, ++n, next->length);
 
-    nargs = param->nargs;
-    args = param->args;
-
-    p.this = (nargs > 1) ? &args[1] : (njs_value_t *) &njs_value_void;
+    this = (param->nargs > 2) ? &args[2] : (njs_value_t *) &njs_value_void;
     p.args = arguments;
     p.nargs = 3;
     p.retval = (njs_index_t) &next->retval;
 
-    return njs_function_apply(vm, args[0].data.u.function, &p);
+    return njs_function_apply(vm, args[1].data.u.function, this, &p);
 }
 
 
 static njs_ret_t
 njs_array_prototype_every(njs_vm_t *vm, njs_param_t *param)
 {
-    uintptr_t         nargs;
     nxt_int_t         n, ret;
     njs_param_t       p;
     njs_array_t       *array;
     njs_value_t       *this, *args, arguments[3];
     njs_array_next_t  *next;
 
-    this = param->this;
+    args = param->args;
 
     if (!vm->frame->reentrant) {
         vm->frame->reentrant = 1;
@@ -913,7 +895,7 @@ njs_array_prototype_every(njs_vm_t *vm, njs_param_t *param)
             return ret;
         }
 
-        array = this->data.u.array;
+        array = args[0].data.u.array;
         n = njs_array_next(array->start, 0, array->length);
         next = njs_native_data(vm->frame);
         next->index = n;
@@ -936,31 +918,28 @@ njs_array_prototype_every(njs_vm_t *vm, njs_param_t *param)
     }
 
     /* GC: array elt, array */
-    array = this->data.u.array;
+    array = args[0].data.u.array;
     arguments[0] = array->start[n];
     njs_number_set(&arguments[1], n);
-    arguments[2] = *this;
+    arguments[2] = args[0];
 
     next->index = njs_array_next(array->start, ++n, next->length);
 
-    nargs = param->nargs;
-    args = param->args;
-
-    p.this = (nargs > 1) ? &args[1] : (njs_value_t *) &njs_value_void;
+    this = (param->nargs > 2) ? &args[2] : (njs_value_t *) &njs_value_void;
     p.args = arguments;
     p.nargs = 3;
     p.retval = (njs_index_t) &next->retval;
 
-    return njs_function_apply(vm, args[0].data.u.function, &p);
+    return njs_function_apply(vm, args[1].data.u.function, this, &p);
 }
 
 
 static nxt_int_t
 njs_array_iterator_args(njs_vm_t *vm, njs_param_t *param)
 {
-    if (njs_is_array(param->this)
-        && param->nargs != 0
-        && njs_is_function(&param->args[0]))
+    if (param->nargs > 1
+        && njs_is_array(&param->args[0])
+        && njs_is_function(&param->args[1]))
     {
         return NXT_OK;
     }
index 5e4213d1945178d7db75068ad7a8c88c0d953b4f..27afc65ecb07513a272e38f05b1cff6fa881bd9b 100644 (file)
@@ -23,11 +23,11 @@ njs_boolean_constructor(njs_vm_t *vm, njs_param_t *param)
     njs_object_t       *object;
     const njs_value_t  *value;
 
-    if (param->nargs == 0) {
+    if (param->nargs == 1) {
         value = &njs_value_false;
 
     } else {
-        value = njs_is_true(&param->args[0]) ? &njs_value_true:
+        value = njs_is_true(&param->args[1]) ? &njs_value_true:
                                                &njs_value_false;
     }
 
@@ -85,7 +85,7 @@ njs_boolean_prototype_value_of(njs_vm_t *vm, njs_param_t *param)
 {
     njs_value_t  *value;
 
-    value = param->this;
+    value = &param->args[0];
 
     if (value->type != NJS_BOOLEAN) {
 
@@ -109,7 +109,7 @@ njs_boolean_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
 {
     njs_value_t  *value;
 
-    value = param->this;
+    value = &param->args[0];
 
     if (value->type != NJS_BOOLEAN) {
 
index 9bf682492054fbba3545afec698adc14182102ff..c0e6b533cfaeeb146a91eabcb81350a990566d38 100644 (file)
@@ -129,7 +129,8 @@ njs_function_constructor(njs_vm_t *vm, njs_param_t *param)
 
 
 nxt_noinline njs_ret_t
-njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_param_t *param)
+njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_value_t *this,
+    njs_param_t *param)
 {
     njs_ret_t  ret;
 
@@ -137,7 +138,7 @@ njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_param_t *param)
         return function->u.native(vm, param);
     }
 
-    ret = njs_function_frame(vm, function, param, 0);
+    ret = njs_function_frame(vm, function, this, param->args, param->nargs, 0);
 
     if (nxt_fast_path(ret == NXT_OK)) {
         return njs_function_call(vm, param->retval, 0);
@@ -148,8 +149,8 @@ njs_function_apply(njs_vm_t *vm, njs_function_t *function, njs_param_t *param)
 
 
 nxt_noinline njs_ret_t
-njs_function_frame(njs_vm_t *vm, njs_function_t *function, njs_param_t *param,
-    nxt_bool_t ctor)
+njs_function_frame(njs_vm_t *vm, njs_function_t *function, njs_value_t *this,
+    njs_value_t *args0, nxt_uint_t nargs0, nxt_bool_t ctor)
 {
     size_t              size;
     uintptr_t           nargs, n;
@@ -157,7 +158,7 @@ njs_function_frame(njs_vm_t *vm, njs_function_t *function, njs_param_t *param,
     njs_frame_t         *frame;
     njs_native_frame_t  *native_frame;
 
-    nargs = nxt_max(param->nargs, function->u.lambda->nargs);
+    nargs = nxt_max(nargs0, function->u.lambda->nargs);
 
     size = NJS_FRAME_SIZE
            + nargs * sizeof(njs_value_t)
@@ -179,13 +180,13 @@ njs_function_frame(njs_vm_t *vm, njs_function_t *function, njs_param_t *param,
 
     frame->local = &args[nargs];
 
-    *args++ = *param->this;
+    *args++ = *this;
     nargs--;
 
-    arguments = param->args;
+    arguments = args0;
 
     if (arguments != NULL) {
-        n = param->nargs;
+        n = nargs0;
 
         while (n != 0) {
             *args++ = *arguments++;
@@ -270,34 +271,34 @@ njs_function_prototype_call(njs_vm_t *vm, njs_param_t *param)
     uintptr_t                   nargs;
     njs_ret_t                   ret;
     njs_param_t                 p;
+    njs_value_t                 *this;
     njs_function_t              *function;
     njs_vmcode_function_call_t  *call;
 
-    if (!njs_is_function(param->this)) {
+    if (!njs_is_function(&param->args[0])) {
         vm->exception = &njs_exception_type_error;
         return NXT_ERROR;
     }
 
-    p.this = &param->args[0];
-    p.args = &param->args[1];
+    this = &param->args[1];
+    p.args = &param->args[2];
 
-    nargs = param->nargs;
-    function = param->this->data.u.function;
+    nargs = param->nargs - 1;
+    function = param->args[0].data.u.function;
 
     if (function->native) {
 
-        if (nargs != 0) {
-            nargs--;
-
-        } else {
-            param->args[0] = njs_value_void;
+        if (nargs == 0) {
+            nargs++;
+            param->args[1] = njs_value_void;
         }
 
+        p.args = &param->args[1];
         p.nargs = nargs;
         p.retval = param->retval;
 
-        ret = njs_normalize_args(vm, &param->args[0], function->args_types,
-                                 nargs + 1);
+        ret = njs_normalize_args(vm, &param->args[1], function->args_types,
+                                 nargs);
         if (ret != NJS_OK) {
             return ret;
         }
@@ -309,12 +310,10 @@ njs_function_prototype_call(njs_vm_t *vm, njs_param_t *param)
         nargs--;
 
     } else {
-        p.this = (njs_value_t *) &njs_value_void;
+        this = (njs_value_t *) &njs_value_void;
     }
 
-    p.nargs = nargs;
-
-    ret = njs_function_frame(vm, function, &p, 0);
+    ret = njs_function_frame(vm, function, this, p.args, nargs, 0);
 
     if (nxt_slow_path(ret != NXT_OK)) {
         return NXT_ERROR;
@@ -337,47 +336,44 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_param_t *param)
     njs_ret_t                   ret;
     njs_param_t                 p;
     njs_array_t                 *array;
-    njs_value_t                 *args;
+    njs_value_t                 *this, *args;
     njs_function_t              *function;
     njs_function_apply_t        *apply;
     njs_vmcode_function_call_t  *code;
 
-    if (!njs_is_function(param->this)) {
-        goto type_error;
-    }
-
     args = param->args;
-    p.this = &args[0];
-
-    nargs = param->nargs;
-    p.nargs = nargs;
-
-    if (nargs > 1) {
-        if (!njs_is_array(&args[1])) {
-            goto type_error;
-        }
 
-        array = args[1].data.u.array;
-        p.args = array->start;
-        p.nargs = array->length;
+    if (!njs_is_function(&args[0])) {
+        goto type_error;
     }
 
-    function = param->this->data.u.function;
+    function = args[0].data.u.function;
 
     if (function->native) {
-        p.retval = param->retval;
 
-        if (nargs < 2) {
-            if (nargs != 0) {
-                p.args = &args[1];
-                p.nargs = nargs - 1;
+        this = &args[1];
+        nargs = param->nargs;
 
-            } else {
+        if (nargs > 2) {
+            if (!njs_is_array(&args[2])) {
                 goto type_error;
             }
+
+            array = args[2].data.u.array;
+            args = array->start;
+            nargs = array->length;
+
+        } else {
+            if (nargs == 1) {
+                this = (njs_value_t *) &njs_value_void;
+            }
+
+            nargs = 0;
         }
 
-        ret = njs_function_apply_frame(vm, function, p.this, p.args, p.nargs);
+        p.retval = param->retval;
+
+        ret = njs_function_apply_frame(vm, function, this, args, nargs);
 
         if (nxt_fast_path(ret == NXT_OK)) {
             apply = nxt_mem_cache_alloc(vm->mem_cache_pool,
@@ -386,15 +382,14 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_param_t *param)
                 return NXT_ERROR;
             }
 
-            p.this = vm->frame->arguments - 1;
-            p.args = vm->frame->arguments;
+            p.args = vm->frame->arguments - 1;
+            p.nargs = nargs + 1;
 
             /* Skip the "apply" method frame. */
             vm->frame->previous->skip = 1;
 
             apply->continuation.function =
                                      njs_function_prototype_apply_continuation;
-            apply->continuation.this = p.this;
             apply->continuation.args = p.args;
             apply->continuation.nargs = p.nargs;
             apply->function = function;
@@ -406,16 +401,31 @@ njs_function_prototype_apply(njs_vm_t *vm, njs_param_t *param)
         return ret;
     }
 
+    this = &args[1];
+
+    nargs = param->nargs - 1;
+    p.nargs = nargs;
+
+    if (nargs > 1) {
+        if (!njs_is_array(&args[2])) {
+            goto type_error;
+        }
+
+        array = args[2].data.u.array;
+        p.args = array->start;
+        p.nargs = array->length;
+    }
+
     if (nargs < 2) {
         if (nargs != 0) {
             p.nargs = 0;
 
         } else {
-            p.this = (njs_value_t *) &njs_value_void;
+            this = (njs_value_t *) &njs_value_void;
         }
     }
 
-    ret = njs_function_frame(vm, function, &p, 0);
+    ret = njs_function_frame(vm, function, this, p.args, p.nargs, 0);
 
     if (nxt_fast_path(ret == NXT_OK)) {
         /* Skip the "apply" method frame. */
@@ -442,7 +452,7 @@ njs_function_apply_frame(njs_vm_t *vm, njs_function_t *function,
     njs_value_t *this, njs_value_t *args, nxt_uint_t nargs)
 {
     size_t              size;
-    njs_value_t         *p;
+    njs_value_t         *arguments;
     njs_native_frame_t  *frame;
 
     size = NJS_NATIVE_FRAME_SIZE + function->local_state_size
@@ -455,16 +465,13 @@ njs_function_apply_frame(njs_vm_t *vm, njs_function_t *function,
 
     frame->function = function;
 
-    p = (njs_value_t *) ((u_char *) njs_native_data(frame)
-                         + function->local_state_size);
-    frame->arguments = p + 1;
+    arguments = (njs_value_t *) ((u_char *) njs_native_data(frame)
+                                 + function->local_state_size);
+    frame->arguments = arguments + 1;
     vm->scopes[NJS_SCOPE_CALLEE_ARGUMENTS] = frame->arguments;
 
-    frame->previous = vm->frame;
-    vm->frame = frame;
-
-    *p = *this;
-    memcpy(p + 1, args, nargs * sizeof(njs_value_t));
+    *arguments = *this;
+    memcpy(arguments + 1, args, nargs * sizeof(njs_value_t));
 
     return NXT_OK;
 }
@@ -478,8 +485,8 @@ njs_function_prototype_apply_continuation(njs_vm_t *vm, njs_param_t *param)
 
     apply = (njs_function_apply_t *) vm->frame->continuation;
 
-    ret = njs_normalize_args(vm, param->this, apply->function->args_types,
-                             param->nargs + 1);
+    ret = njs_normalize_args(vm, param->args, apply->function->args_types,
+                             param->nargs);
     if (ret != NJS_OK) {
         return ret;
     }
@@ -493,7 +500,7 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_param_t *param)
 {
     njs_function_t  *bound;
 
-    if (!njs_is_function(param->this)) {
+    if (!njs_is_function(&param->args[0])) {
         vm->exception = &njs_exception_type_error;
         return NXT_ERROR;
     }
@@ -505,7 +512,7 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_param_t *param)
         nxt_lvlhsh_init(&bound->object.shared_hash);
         bound->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION];
         bound->args_offset = 1;
-        bound->u.lambda = param->this->data.u.function->u.lambda;
+        bound->u.lambda = param->args[0].data.u.function->u.lambda;
 
         vm->retval.data.u.function = bound;
         vm->retval.type = NJS_FUNCTION;
index 5e7379780be09b7d6dcc0a0d69c14398b486a70f..4ffae48fac3e9806ad894f1ef57ce9daedfabcfd 100644 (file)
@@ -54,7 +54,6 @@ struct njs_function_lambda_s {
 
 typedef struct {
     njs_native_t                   function;
-    njs_value_t                    *this;
     njs_value_t                    *args;
     nxt_uint_t                     nargs;
 } njs_continuation_t;
@@ -135,11 +134,11 @@ njs_function_t *njs_function_alloc(njs_vm_t *vm);
 njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size);
 njs_ret_t njs_function_constructor(njs_vm_t *vm, njs_param_t *param);
 njs_ret_t njs_function_apply(njs_vm_t *vm, njs_function_t *function,
-    njs_param_t *param);
+    njs_value_t *this, njs_param_t *param);
 njs_value_t *njs_function_native_frame(njs_vm_t *vm, njs_function_t *function,
     njs_vmcode_t *code);
 njs_ret_t njs_function_frame(njs_vm_t *vm, njs_function_t *function,
-    njs_param_t *param, nxt_bool_t ctor);
+    njs_value_t *this, njs_value_t *args, nxt_uint_t nargs, nxt_bool_t ctor);
 njs_ret_t njs_function_call(njs_vm_t *vm, njs_index_t retval, size_t advance);
 
 extern const njs_object_init_t  njs_function_constructor_init;
index 3f479e326c187c2570825bc5b0d07887039ee82d..e926263d3f177df87034751a3c4587888d71c6e0 100644 (file)
@@ -218,11 +218,11 @@ njs_number_constructor(njs_vm_t *vm, njs_param_t *param)
     njs_object_t       *object;
     const njs_value_t  *value;
 
-    if (param->nargs == 0) {
+    if (param->nargs == 1) {
         value = &njs_value_zero;
 
     } else {
-        value = &param->args[0];
+        value = &param->args[1];
     }
 
     if (vm->frame->ctor) {
@@ -279,7 +279,7 @@ njs_number_prototype_value_of(njs_vm_t *vm, njs_param_t *param)
 {
     njs_value_t  *value;
 
-    value = param->this;
+    value = &param->args[0];
 
     if (value->type != NJS_NUMBER) {
 
@@ -303,7 +303,7 @@ njs_number_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
 {
     njs_value_t  *value;
 
-    value = param->this;
+    value = &param->args[0];
 
     if (value->type != NJS_NUMBER) {
 
index 48be012f86589c7e7554ffeb6cef698e5322b23e..282fad4bfd00efee8e274b2eaa04356ea3489e17 100644 (file)
@@ -208,7 +208,7 @@ njs_object_constructor(njs_vm_t *vm, njs_param_t *param)
 
     type = NJS_OBJECT;
 
-    if (param->nargs == 0 || njs_is_null_or_void(&param->args[0])) {
+    if (param->nargs == 1 || njs_is_null_or_void(&param->args[1])) {
 
         object = njs_object_alloc(vm);
         if (nxt_slow_path(object == NULL)) {
@@ -216,7 +216,7 @@ njs_object_constructor(njs_vm_t *vm, njs_param_t *param)
         }
 
     } else {
-        value = &param->args[0];
+        value = &param->args[1];
 
         if (njs_is_object(value)) {
             object = value->data.u.object;
@@ -254,19 +254,19 @@ njs_object_create(njs_vm_t *vm, njs_param_t *param)
     njs_value_t   *args;
     njs_object_t  *object;
 
-    if (param->nargs != 0) {
+    if (param->nargs > 1) {
         args = param->args;
 
-        if (njs_is_object(&args[0]) || njs_is_null(&args[0])) {
+        if (njs_is_object(&args[1]) || njs_is_null(&args[1])) {
 
             object = njs_object_alloc(vm);
             if (nxt_slow_path(object == NULL)) {
                 return NXT_ERROR;
             }
 
-            if (!njs_is_null(&args[0])) {
+            if (!njs_is_null(&args[1])) {
                 /* GC */
-                object->__proto__ = args[0].data.u.object;
+                object->__proto__ = args[1].data.u.object;
 
             } else {
                 object->shared_hash = vm->shared->null_proto_hash;
@@ -509,7 +509,7 @@ found:
 static njs_ret_t
 njs_object_prototype_value_of(njs_vm_t *vm, njs_param_t *param)
 {
-    vm->retval = *param->this;
+    vm->retval = param->args[0];
 
     return NXT_OK;
 }
@@ -538,7 +538,7 @@ njs_ret_t
 njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
 {
     int32_t       index;
-    njs_value_t   *this;
+    njs_value_t   *args;
     njs_object_t  *prototype;
 
     static const njs_value_t  *class_name[] = {
@@ -563,11 +563,11 @@ njs_object_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
         &njs_object_regexp_string,
     };
 
-    this = param->this;
-    index = this->type;
+    args = param->args;
+    index = args[0].type;
 
-    if (njs_is_object(this)) {
-        prototype = this->data.u.object;
+    if (njs_is_object(&args[0])) {
+        prototype = args[0].data.u.object;
 
         do {
             index = prototype - vm->prototypes;
index 54edc1239eea73b8638dd946a8456bc81d4eb9c7..e4a5d71745c05bab0c8d89c262a96a89558cb4ef 100644 (file)
@@ -51,7 +51,7 @@ njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param)
     switch (param->nargs) {
 
     default:
-        length = njs_string_prop(&string, &param->args[1]);
+        length = njs_string_prop(&string, &param->args[2]);
 
         flags = njs_regexp_flags(&string.start, string.start + length, 1);
         if (nxt_slow_path(flags < 0)) {
@@ -60,8 +60,8 @@ njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param)
 
         /* Fall through. */
 
-    case 1:
-        string.length = njs_string_prop(&string, &param->args[0]);
+    case 2:
+        string.length = njs_string_prop(&string, &param->args[1]);
 
         if (string.length != 0) {
             break;
@@ -69,7 +69,7 @@ njs_regexp_constructor(njs_vm_t *vm, njs_param_t *param)
 
         /* Fall through. */
 
-    case 0:
+    case 1:
         string.start = (u_char *) "(?:)";
         string.length = sizeof("(?:)") - 1;
         break;
@@ -444,7 +444,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_param_t *param)
     size_t                length, size;
     njs_regexp_pattern_t  *pattern;
 
-    pattern = param->this->data.u.regexp->pattern;
+    pattern = param->args[0].data.u.regexp->pattern;
     source = pattern->source;
 
     size = strlen((char *) source);
@@ -464,15 +464,15 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_param_t *param)
     njs_string_prop_t     string;
     njs_regexp_pattern_t  *pattern;
 
-    if (!njs_is_regexp(param->this)) {
+    if (!njs_is_regexp(&param->args[0])) {
         vm->exception = &njs_exception_type_error;
         return NXT_ERROR;
     }
 
     retval = &njs_value_false;
 
-    if (param->nargs != 0) {
-        value = &param->args[0];
+    if (param->nargs > 1) {
+        value = &param->args[1];
 
     } else {
         value = (njs_value_t *) &njs_string_void;
@@ -482,7 +482,7 @@ njs_regexp_prototype_test(njs_vm_t *vm, njs_param_t *param)
 
     n = (string.length != 0 && string.length != string.size);
 
-    pattern = param->this->data.u.regexp->pattern;
+    pattern = param->args[0].data.u.regexp->pattern;
 
     if (pattern->code[n] != NULL) {
         ret = pcre_exec(pattern->code[n], pattern->extra[n],
@@ -514,19 +514,19 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_param_t *param)
     njs_string_prop_t     string;
     njs_regexp_pattern_t  *pattern;
 
-    if (!njs_is_regexp(param->this)) {
+    if (!njs_is_regexp(&param->args[0])) {
         vm->exception = &njs_exception_type_error;
         return NXT_ERROR;
     }
 
-    if (param->nargs != 0) {
-        value = &param->args[0];
+    if (param->nargs > 1) {
+        value = &param->args[1];
 
     } else {
         value = (njs_value_t *) &njs_string_void;
     }
 
-    regexp = param->this->data.u.regexp;
+    regexp = param->args[0].data.u.regexp;
     regexp->string = *value;
 
     (void) njs_string_prop(&string, value);
index 470bc2c187b75f10eeb0c4efb7de33c033689642..73b31e8caa1c98ea1f19feb0299d1b0f2965b6a3 100644 (file)
@@ -256,11 +256,11 @@ njs_string_constructor(njs_vm_t *vm, njs_param_t *param)
     njs_object_t       *object;
     const njs_value_t  *value;
 
-    if (param->nargs == 0) {
+    if (param->nargs == 1) {
         value = &njs_string_empty;
 
     } else {
-        value = &param->args[0];
+        value = &param->args[1];
     }
 
     if (vm->frame->ctor) {
@@ -452,7 +452,7 @@ njs_string_prototype_value_of(njs_vm_t *vm, njs_param_t *param)
 {
     njs_value_t  *value;
 
-    value = param->this;
+    value = &param->args[0];
 
     if (value->type != NJS_STRING) {
 
@@ -482,20 +482,19 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_param_t *param)
     size_t             size, length, mask;
     uintptr_t          nargs;
     nxt_uint_t         i;
-    njs_value_t        *this, *args;
+    njs_value_t        *args;
     njs_string_prop_t  string;
 
-    this = param->this;
-    nargs = param->nargs;
+    args = param->args;
 
-    if (njs_is_null_or_void(this)) {
+    if (njs_is_null_or_void(&args[0])) {
         vm->exception = &njs_exception_type_error;
         return NXT_ERROR;
     }
 
-    args = param->args - 1;
+    nargs = param->nargs;
 
-    for (i = 0; i <= nargs; i++) {
+    for (i = 0; i < nargs; i++) {
 
         if (!njs_is_string(&args[i])) {
             vm->frame->trap_scratch.data.u.value = &args[i];
@@ -504,19 +503,14 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_param_t *param)
         }
     }
 
-    if (nargs == 0) {
-        njs_string_copy(&vm->retval, this);
+    if (nargs == 1) {
+        njs_string_copy(&vm->retval, &args[0]);
         return NXT_OK;
     }
 
-    (void) njs_string_prop(&string, this);
-
-    size = string.size;
-    length = string.length;
-
-    mask = (string.length == 0 && string.size != 0) ? 0 : -1;
-
-    args = param->args;
+    size = 0;
+    length = 0;
+    mask = -1;
 
     for (i = 0; i < nargs; i++) {
         (void) njs_string_prop(&string, &args[i]);
@@ -537,10 +531,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_param_t *param)
         return NXT_ERROR;
     }
 
-    (void) njs_string_prop(&string, this);
-
-    p = memcpy(start, string.start, string.size);
-    p += string.size;
+    p = start;
 
     for (i = 0; i < nargs; i++) {
         (void) njs_string_prop(&string, &args[i]);
@@ -618,7 +609,7 @@ njs_string_prototype_to_utf8(njs_vm_t *vm, njs_param_t *param)
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    (void) njs_string_prop(&string, param->this);
+    (void) njs_string_prop(&string, &param->args[0]);
 
     string.length = 0;
     slice.string_length = string.size;
@@ -772,21 +763,21 @@ njs_string_prototype_substring(njs_vm_t *vm, njs_param_t *param)
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    length = njs_string_prop(&string, param->this);
+    length = njs_string_prop(&string, &param->args[0]);
 
     slice.string_length = length;
     start = 0;
     nargs = param->nargs;
 
-    if (nargs != 0) {
-        start = param->args[0].data.u.number;
+    if (nargs > 1) {
+        start = param->args[1].data.u.number;
 
         if (start < 0) {
             start = 0;
         }
 
-        if (nargs > 1) {
-            end = param->args[1].data.u.number;
+        if (nargs > 2) {
+            end = param->args[2].data.u.number;
 
             if (end < 0) {
                 end = 0;
@@ -821,14 +812,14 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_param_t *param)
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    length = njs_string_prop(&string, param->this);
+    length = njs_string_prop(&string, &param->args[0]);
 
     slice.string_length = length;
     start = 0;
     nargs = param->nargs;
 
-    if (nargs != 0) {
-        start = param->args[0].data.u.number;
+    if (nargs > 1) {
+        start = param->args[1].data.u.number;
 
         if (start < 0) {
 
@@ -838,8 +829,8 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_param_t *param)
             }
         }
 
-        if (nargs > 1) {
-            length = param->args[1].data.u.number;
+        if (nargs > 2) {
+            length = param->args[2].data.u.number;
         }
     }
 
@@ -857,13 +848,13 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_param_t *param)
     njs_slice_prop_t   slice;
     njs_string_prop_t  string;
 
-    slice.string_length = njs_string_prop(&string, param->this);
+    slice.string_length = njs_string_prop(&string, &param->args[0]);
 
     start = 0;
     length = 1;
 
-    if (param->nargs != 0) {
-        start = param->args[0].data.u.number;
+    if (param->nargs > 1) {
+        start = param->args[1].data.u.number;
 
         if (start < 0) {
             length = 0;
@@ -881,7 +872,7 @@ static nxt_noinline void
 njs_string_slice_prop(njs_param_t *param, njs_string_prop_t *string,
     njs_slice_prop_t *slice)
 {
-    slice->string_length = njs_string_prop(string, param->this);
+    slice->string_length = njs_string_prop(string, &param->args[0]);
 
     njs_string_slice_params(param, slice);
 }
@@ -897,8 +888,8 @@ njs_string_slice_params(njs_param_t *param, njs_slice_prop_t *slice)
     start = 0;
     nargs = param->nargs;
 
-    if (nargs != 0) {
-        start = param->args[0].data.u.number;
+    if (nargs > 1) {
+        start = param->args[1].data.u.number;
 
         if (start < 0) {
             start += length;
@@ -910,8 +901,8 @@ njs_string_slice_params(njs_param_t *param, njs_slice_prop_t *slice)
 
         end = length;
 
-        if (nargs > 1) {
-            end = param->args[1].data.u.number;
+        if (nargs > 2) {
+            end = param->args[2].data.u.number;
 
             if (end < 0) {
                 end += length;
@@ -1011,12 +1002,12 @@ njs_string_prototype_char_code_at(njs_vm_t *vm, njs_param_t *param)
     const u_char       *start, *end;
     njs_string_prop_t  string;
 
-    length = njs_string_prop(&string, param->this);
+    length = njs_string_prop(&string, &param->args[0]);
 
     index = 0;
 
-    if (param->nargs != 0) {
-        index = param->args[0].data.u.number;
+    if (param->nargs > 1) {
+        index = param->args[1].data.u.number;
 
         if (nxt_slow_path(index < 0 || index >= length)) {
             num = NJS_NAN;
@@ -1050,22 +1041,24 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_param_t *param)
 {
     ssize_t    start, index;
     uintptr_t  nargs;
+    njs_value_t  *args;
 
     index = -1;
+    args = param->args;
     nargs = param->nargs;
 
-    if (nargs != 0) {
+    if (nargs > 1) {
         start = 0;
 
-        if (nargs > 1) {
-            start = param->args[1].data.u.number;
+        if (nargs > 2) {
+            start = args[2].data.u.number;
 
             if (start < 0) {
                 start = 0;
             }
         }
 
-        index = njs_string_index_of(vm, param->this, &param->args[0], start);
+        index = njs_string_index_of(vm, &args[0], &args[1], start);
     }
 
     njs_number_set(&vm->retval, index);
@@ -1077,17 +1070,19 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_param_t *param)
 static njs_ret_t
 njs_string_prototype_last_index_of(njs_vm_t *vm, njs_param_t *param)
 {
-    ssize_t    ret, index, last;
-    uintptr_t  nargs;
+    ssize_t      ret, index, last;
+    uintptr_t    nargs;
+    njs_value_t  *args;
 
     index = -1;
+    args = param->args;
     nargs = param->nargs;
 
-    if (nargs != 0) {
+    if (nargs > 1) {
         last = NJS_STRING_MAX_LENGTH;
 
-        if (nargs > 1) {
-            last = param->args[1].data.u.number;
+        if (nargs > 2) {
+            last = args[2].data.u.number;
 
             if (last < 0) {
                 last = 0;
@@ -1097,7 +1092,7 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_param_t *param)
         ret = 0;
 
         for ( ;; ) {
-            ret = njs_string_index_of(vm, param->this, &param->args[0], ret);
+            ret = njs_string_index_of(vm, &args[0], &args[1], ret);
 
             if (ret < 0 || ret >= last) {
                 break;
@@ -1237,15 +1232,15 @@ njs_string_prototype_search(njs_vm_t *vm, njs_param_t *param)
 
     index = 0;
 
-    if (param->nargs != 0) {
+    if (param->nargs > 1) {
 
-        switch (param->args[0].type) {
+        switch (param->args[1].type) {
 
         case NJS_VOID:
             goto done;
 
         case NJS_STRING:
-            (void) njs_string_prop(&string, &param->args[0]);
+            (void) njs_string_prop(&string, &param->args[1]);
 
             if (string.size == 0) {
                 goto done;
@@ -1260,12 +1255,12 @@ njs_string_prototype_search(njs_vm_t *vm, njs_param_t *param)
             break;
 
         default:  /* NJS_REGEXP */
-            pattern = param->args[0].data.u.regexp->pattern;
+            pattern = param->args[1].data.u.regexp->pattern;
         }
 
         index = -1;
 
-        (void) njs_string_prop(&string, param->this);
+        (void) njs_string_prop(&string, &param->args[0]);
 
         n = (string.length != 0 && string.length != string.size);
 
@@ -1303,25 +1298,25 @@ njs_string_prototype_match(njs_vm_t *vm, njs_param_t *param)
     int32_t               size, length;
     njs_ret_t             ret;
     nxt_uint_t            n, utf8;
-    njs_value_t           *args;
+    njs_value_t           *args, tmp;
     njs_array_t           *array;
     njs_string_prop_t     string;
     njs_regexp_pattern_t  *pattern;
     int                   captures[3];
 
-    if (param->nargs == 0) {
+    if (param->nargs == 1) {
         goto empty;
     }
 
     args = param->args;
 
-    switch (args[0].type) {
+    switch (args[1].type) {
 
     case NJS_VOID:
         goto empty;
 
     case NJS_STRING:
-        (void) njs_string_prop(&string, &args[0]);
+        (void) njs_string_prop(&string, &args[1]);
 
         if (string.size == 0) {
             goto empty;
@@ -1335,16 +1330,16 @@ njs_string_prototype_match(njs_vm_t *vm, njs_param_t *param)
         break;
 
     default:  /* NJS_REGEXP */
-        pattern = args[0].data.u.regexp->pattern;
+        pattern = args[1].data.u.regexp->pattern;
 
         if (!pattern->global) {
             /*
              * string.match(regexp) is the same as regexp.exec(string)
              * if the regexp has no global flag.
              */
-            param->args = param->this;
-            param->this = args;
-            param->nargs = 1;
+            tmp = args[0];
+            args[0] = args[1];
+            args[1] = tmp;
 
             return njs_regexp_prototype_exec(vm, param);
         }
@@ -1352,7 +1347,7 @@ njs_string_prototype_match(njs_vm_t *vm, njs_param_t *param)
 
     vm->retval = njs_value_null;
 
-    (void) njs_string_prop(&string, param->this);
+    (void) njs_string_prop(&string, &param->args[0]);
 
     utf8 = 0;
     n = 0;
@@ -1442,8 +1437,8 @@ njs_string_prototype_match(njs_vm_t *vm, njs_param_t *param)
         } while (string.size > 0);
     }
 
-    if (njs_is_regexp(&args[0])) {
-        args[0].data.u.regexp->last_index = 0;
+    if (njs_is_regexp(&args[1])) {
+        args[1].data.u.regexp->last_index = 0;
     }
 
     return NXT_OK;
index a6c2f3ed27723ec006bc1f14241a0f8eac54dacf..9618219ae9291c3fb0e147cff833399bfc7e6886 100644 (file)
@@ -2084,7 +2084,6 @@ njs_vmcode_function_frame(njs_vm_t *vm, njs_value_t *invld, njs_value_t *name)
 {
     njs_ret_t                    ret;
     njs_value_t                  val, *this, *value;
-    njs_param_t                  param;
     njs_object_t                 *object;
     njs_function_t               *function;
     njs_vmcode_function_frame_t  *func;
@@ -2118,16 +2117,14 @@ njs_vmcode_function_frame(njs_vm_t *vm, njs_value_t *invld, njs_value_t *name)
             val.data.u.object = object;
             val.type = NJS_OBJECT;
             val.data.truth = 1;
-            param.this = &val;
+            this = &val;
 
         } else {
-            param.this = (njs_value_t *) &njs_value_void;
+            this = (njs_value_t *) &njs_value_void;
         }
 
-        param.args = NULL;
-        param.nargs = func->code.nargs;
-
-        ret = njs_function_frame(vm, function, &param, func->code.ctor);
+        ret = njs_function_frame(vm, function, this, NULL, func->code.nargs,
+                                 func->code.ctor);
 
         if (nxt_fast_path(ret == NXT_OK)) {
             return sizeof(njs_vmcode_function_frame_t);
@@ -2147,7 +2144,6 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *name, njs_value_t *object)
 {
     njs_ret_t                  ret;
     njs_value_t                *this;
-    njs_param_t                param;
     njs_extern_t               *ext;
     njs_function_t             *function;
     njs_object_prop_t          *prop;
@@ -2169,11 +2165,8 @@ njs_vmcode_method_frame(njs_vm_t *vm, njs_value_t *name, njs_value_t *object)
             function = prop->value.data.u.function;
 
             if (!function->native) {
-                param.this = object;
-                param.args = NULL;
-                param.nargs = method->code.nargs;
-
-                ret = njs_function_frame(vm, function, &param,
+                ret = njs_function_frame(vm, function, object, NULL,
+                                         method->code.nargs,
                                          method->code.ctor);
 
                 if (nxt_fast_path(ret == NXT_OK)) {
@@ -2263,15 +2256,13 @@ njs_vmcode_function_call(njs_vm_t *vm, njs_value_t *invld, njs_value_t *retval)
             return ret;
         }
 
-        param.args = args;
-        param.this = args - 1;
-        param.nargs = call->code.nargs - 1;
+        param.args = args - 1;
+        param.nargs = call->code.nargs;
         param.retval = (njs_index_t) retval;
 
         native = function->u.native;
 
     } else {
-        param.this = continuation->this;
         param.args = continuation->args;
         param.retval = (njs_index_t) retval;
         param.nargs = continuation->nargs;
@@ -2942,7 +2933,6 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint)
     continuation = vm->frame->continuation;
 
     if (continuation != NULL) {
-        param.this = continuation->this;
         param.args = continuation->args;
         param.nargs = continuation->nargs;
         param.retval = (njs_index_t) &vm->frame->trap_scratch;
@@ -2986,14 +2976,13 @@ njs_primitive_value(njs_vm_t *vm, njs_value_t *value, nxt_uint_t hint)
                             continue;
                         }
 
-                        param.this = value;
                         param.retval = (njs_index_t) retval;
-                        param.args = NULL;
+                        param.args = value;
                         param.nargs = 0;
 
                         ret = njs_function_apply(vm,
                                                  prop->value.data.u.function,
-                                                 &param);
+                                                 value, &param);
                         /*
                          * njs_function_apply() can return
                          *   NXT_OK, NJS_APPLIED, NXT_ERROR, NXT_AGAIN.
index dbae4530291965f8a1ed3f1a2a993ac5cc31229b..ce6f3fff5964e6b06fb159a1f3b0cc5853875cc1 100644 (file)
@@ -15,7 +15,6 @@ typedef union  njs_value_s          njs_value_t;
 typedef struct njs_vm_shared_s      njs_vm_shared_t;
 
 typedef struct {
-    njs_value_t                     *this;
     njs_value_t                     *args;
     uintptr_t                       nargs;
     njs_index_t                     retval;
index 18007a62a9a7ef177adbc4ca47dd7b963f9e3cd6..288fe5768c3e8bc71ac0cd1024d3db5d60382d01 100644 (file)
@@ -2133,11 +2133,13 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("a = [1,2,3]; a.shift() +' '+ a[0] +' '+ a.length"),
       nxt_string("1 2 2") },
 
-    { nxt_string("a = [1,2]; len = a.unshift(3); len +' '+ a.shift()"),
-      nxt_string("3 3") },
+    { nxt_string("a = [1,2]; len = a.unshift(3);"
+                 "len +' '+ a +' '+ a.shift()"),
+      nxt_string("3 3,1,2 3") },
 
-    { nxt_string("a = [1,2]; len = a.unshift(3,4,5); len +' '+ a.shift()"),
-      nxt_string("5 3") },
+    { nxt_string("a = [1,2]; len = a.unshift(3,4,5);"
+                 "len +' '+ a +' '+ a.shift()"),
+      nxt_string("5 3,4,5,1,2 3") },
 
     { nxt_string("var a = []; var s = { sum: 0 };"
                  "a.forEach(function(v, i, a) { this.sum += v }, s); s.sum"),
@@ -3895,13 +3897,13 @@ njs_unit_test_method_external(njs_vm_t *vm, njs_param_t *param)
 
     next = 0;
 
-    if (param->nargs != 0) {
+    if (param->nargs > 1) {
 
-        ret = njs_value_string_copy(vm, &s, njs_argument(param->args, 0),
+        ret = njs_value_string_copy(vm, &s, njs_argument(param->args, 1),
                                     &next);
 
         if (ret == NXT_OK && s.len == 3 && memcmp(s.data, "YES", 3) == 0) {
-            r = njs_value_data(param->this);
+            r = njs_value_data(njs_argument(param->args, 0));
             njs_vm_return_string(vm, r->uri.data, r->uri.len);
 
             return NXT_OK;