Skip to content

Commit 42ba64c

Browse files
committed
Ref to function self should not create new object
Picked from yodaos-project/ShadowNode#368 JerryScript-DCO-1.0-Signed-off-by: legendecas legendecas@gmail.com
1 parent 3f9dd0f commit 42ba64c

File tree

5 files changed

+51
-9
lines changed

5 files changed

+51
-9
lines changed

jerry-core/ecma/operations/ecma-function-object.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
716716
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
717717
}
718718

719-
ecma_value_t ret_value = vm_run (bytecode_data_p,
719+
ecma_value_t ret_value = vm_run (ext_func_p,
720+
bytecode_data_p,
720721
this_binding,
721722
local_env_p,
722723
ECMA_PARSE_NO_OPTS,
@@ -779,7 +780,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
779780
JERRY_ASSERT (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED));
780781
}
781782

782-
ecma_value_t ret_value = vm_run (bytecode_data_p,
783+
ecma_value_t ret_value = vm_run (NULL,
784+
bytecode_data_p,
783785
arrow_func_p->this_binding,
784786
local_env_p,
785787
ECMA_PARSE_NO_OPTS,

jerry-core/vm/vm-defines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef const uint8_t *vm_instr_counter_t;
4545
*/
4646
typedef struct vm_frame_ctx_t
4747
{
48+
const ecma_extended_object_t *func_obj_p; /**< currently executed fucntion */
4849
const ecma_compiled_code_t *bytecode_header_p; /**< currently executed byte-code data */
4950
uint8_t *byte_code_p; /**< current byte code pointer */
5051
uint8_t *byte_code_start_p; /**< byte code start pointer */

jerry-core/vm/vm.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode
224224
{
225225
ecma_object_t *glob_obj_p = ecma_builtin_get_global ();
226226

227-
return vm_run (bytecode_p,
227+
return vm_run (NULL,
228+
bytecode_p,
228229
ecma_make_object_value (glob_obj_p),
229230
ecma_get_global_environment (),
230231
false,
@@ -288,7 +289,8 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
288289
lex_env_p = strict_lex_env_p;
289290
}
290291

291-
ecma_value_t completion_value = vm_run (bytecode_data_p,
292+
ecma_value_t completion_value = vm_run (NULL,
293+
bytecode_data_p,
292294
this_binding,
293295
lex_env_p,
294296
parse_opts,
@@ -733,8 +735,16 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
733735
else
734736
{
735737
is_immutable_binding = (self_reference == literal_start_p[value_index]);
736-
lit_value = vm_construct_literal_object (frame_ctx_p,
737-
literal_start_p[value_index]);
738+
if (is_immutable_binding)
739+
{
740+
lit_value = ecma_make_object_value ((ecma_object_t*) frame_ctx_p->func_obj_p);
741+
ecma_ref_object ((ecma_object_t*) frame_ctx_p->func_obj_p);
742+
}
743+
else
744+
{
745+
lit_value = vm_construct_literal_object (frame_ctx_p,
746+
literal_start_p[value_index]);
747+
}
738748
}
739749

740750
if (literal_index < register_end)
@@ -3471,7 +3481,8 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
34713481
* @return ecma value
34723482
*/
34733483
ecma_value_t
3474-
vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */
3484+
vm_run (const ecma_extended_object_t *func_obj_p, /**< function object */
3485+
const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */
34753486
ecma_value_t this_binding_value, /**< value of 'ThisBinding' */
34763487
ecma_object_t *lex_env_p, /**< lexical environment to use */
34773488
uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
@@ -3502,7 +3513,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
35023513
frame_ctx.literal_start_p = literal_p;
35033514
literal_p += args_p->literal_end;
35043515
}
3505-
3516+
frame_ctx.func_obj_p = func_obj_p;
35063517
frame_ctx.bytecode_header_p = bytecode_header_p;
35073518
frame_ctx.byte_code_p = (uint8_t *) literal_p;
35083519
frame_ctx.byte_code_start_p = (uint8_t *) literal_p;

jerry-core/vm/vm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ typedef enum
353353
ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p);
354354
ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_opts);
355355

356-
ecma_value_t vm_run (const ecma_compiled_code_t *bytecode_header_p, ecma_value_t this_binding_value,
356+
ecma_value_t vm_run (const ecma_extended_object_t *func_obj_p,
357+
const ecma_compiled_code_t *bytecode_header_p, ecma_value_t this_binding_value,
357358
ecma_object_t *lex_env_p, uint32_t parse_opts, const ecma_value_t *arg_list_p,
358359
ecma_length_t arg_list_len);
359360

tests/jerry/function-self-ref.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright JS Foundation and other contributors, http://js.foundation
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
var foo = function bar() {
16+
assert(foo === bar);
17+
};
18+
foo();
19+
20+
var globalFunc;
21+
function foo(func) {
22+
globalFunc = func;
23+
}
24+
25+
foo(function bar() {
26+
assert(globalFunc === bar);
27+
});

0 commit comments

Comments
 (0)