From bd4ea6ffca62d060dfb7cf4541351d7bfbc995a9 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 26 Jun 2018 18:30:10 +0700 Subject: [PATCH] Returning external methods as native Function objects. This fixes #20 issue on GitHub. --- njs/njs_extern.c | 27 +++++++++++++++++++++------ njs/njs_vm.c | 6 ++++++ njs/test/njs_expect_test.exp | 5 +++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/njs/njs_extern.c b/njs/njs_extern.c index d24b437d..29ff3315 100644 --- a/njs/njs_extern.c +++ b/njs/njs_extern.c @@ -75,6 +75,7 @@ njs_vm_external_add(njs_vm_t *vm, nxt_lvlhsh_t *hash, njs_external_t *external, { nxt_int_t ret; njs_extern_t *ext, *child; + njs_function_t *function; nxt_lvlhsh_query_t lhq; do { @@ -96,15 +97,29 @@ njs_vm_external_add(njs_vm_t *vm, nxt_lvlhsh_t *hash, njs_external_t *external, ext->data = external->data; if (external->method != NULL) { - ext->function = nxt_mem_cache_zalloc(vm->mem_cache_pool, - sizeof(njs_function_t)); - if (nxt_slow_path(ext->function == NULL)) { + function = nxt_mem_cache_zalloc(vm->mem_cache_pool, + sizeof(njs_function_t)); + if (nxt_slow_path(function == NULL)) { return NULL; } - ext->function->native = 1; - ext->function->args_offset = 1; - ext->function->u.native = external->method; + /* + * nxt_mem_cache_zalloc() does also: + * nxt_lvlhsh_init(&function->object.hash); + * function->object.__proto__ = NULL; + */ + + function->object.__proto__ = + &vm->prototypes[NJS_CONSTRUCTOR_FUNCTION].object; + function->object.shared_hash = vm->shared->function_prototype_hash; + function->object.type = NJS_FUNCTION; + function->object.shared = 1; + function->object.extensible = 1; + function->args_offset = 1; + function->native = 1; + function->u.native = external->method; + + ext->function = function; } else { ext->function = NULL; diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 11192721..5c577031 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -588,6 +588,12 @@ njs_vmcode_property_get(njs_vm_t *vm, njs_value_t *object, /* The vm->retval is already retained by ext_proto->get(). */ } + if (ext_proto->type == NJS_EXTERN_METHOD) { + vm->retval.data.u.function = ext_proto->function; + vm->retval.type = NJS_FUNCTION; + vm->retval.data.truth = 1; + } + return sizeof(njs_vmcode_prop_get_t); case NJS_TRAP_PROPERTY: diff --git a/njs/test/njs_expect_test.exp b/njs/test/njs_expect_test.exp index ef9b5e52..81150a02 100644 --- a/njs/test/njs_expect_test.exp +++ b/njs/test/njs_expect_test.exp @@ -176,6 +176,11 @@ njs_test { "console.ll()\r\nTypeError: cannot find property 'll' of an external object"} } +njs_test { + {"var print = console.log.bind(console); print(1, 'a', [1, 2])\r\n" + "var print = console.log.bind(console); print(1, 'a', \\\[1, 2])\r\n1 a 1,2\r\nundefined\r\n>> "} +} + # Backtraces for external objects njs_test { {"console.log(console)\r\n" -- 2.47.3