Fix super property assignment for namedaccessor properties (#3654)
Tha patch also updates the [[Put]] internal method with the new steps from the ES6 standard. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
@@ -1132,12 +1132,87 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
|
||||
is_throw);
|
||||
} /* ecma_op_object_put */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
/**
|
||||
* [[Set]] ( P, V, Receiver) operation part for ordinary objects
|
||||
*
|
||||
* See also: ECMAScript v6, 9.19.9
|
||||
*
|
||||
* @return ecma value
|
||||
* The returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_op_object_put_apply_receiver (ecma_value_t receiver, /**< receiver */
|
||||
ecma_string_t *property_name_p, /**< property name */
|
||||
ecma_value_t value, /**< value to set */
|
||||
bool is_throw) /**< flag that controls failure handling */
|
||||
{
|
||||
/* 5.b */
|
||||
if (!ecma_is_value_object (receiver))
|
||||
{
|
||||
return ecma_reject (is_throw);
|
||||
}
|
||||
|
||||
ecma_object_t *receiver_obj_p = ecma_get_object_from_value (receiver);
|
||||
|
||||
ecma_property_descriptor_t prop_desc;
|
||||
/* 5.c */
|
||||
ecma_value_t status = ecma_op_object_get_own_property_descriptor (receiver_obj_p,
|
||||
property_name_p,
|
||||
&prop_desc);
|
||||
|
||||
/* 5.d */
|
||||
if (ECMA_IS_VALUE_ERROR (status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* 5.e */
|
||||
if (ecma_is_value_true (status))
|
||||
{
|
||||
ecma_value_t result;
|
||||
|
||||
/* 5.e.i - 5.e.ii */
|
||||
if (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)
|
||||
|| !(prop_desc.flags & ECMA_PROP_IS_WRITABLE))
|
||||
{
|
||||
result = ecma_reject (is_throw);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 5.e.iii */
|
||||
JERRY_ASSERT (prop_desc.flags & ECMA_PROP_IS_VALUE_DEFINED);
|
||||
ecma_free_value (prop_desc.value);
|
||||
prop_desc.value = ecma_copy_value (value);
|
||||
|
||||
/* 5.e.iv */
|
||||
result = ecma_op_object_define_own_property (receiver_obj_p, property_name_p, &prop_desc);
|
||||
}
|
||||
|
||||
ecma_free_property_descriptor (&prop_desc);
|
||||
|
||||
return result;
|
||||
}
|
||||
/* 5.f.i */
|
||||
ecma_property_value_t *new_prop_value_p;
|
||||
new_prop_value_p = ecma_create_named_data_property (receiver_obj_p,
|
||||
property_name_p,
|
||||
ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
|
||||
NULL);
|
||||
JERRY_ASSERT (ecma_is_value_undefined (new_prop_value_p->value));
|
||||
new_prop_value_p->value = ecma_copy_value_if_not_object (value);
|
||||
|
||||
return ECMA_VALUE_TRUE;
|
||||
} /* ecma_op_object_put_apply_receiver */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
* [[Put]] ecma general object's operation with given receiver
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8
|
||||
* ECMA-262 v5, 8.12.5
|
||||
* ECMA-262 v6, 9.1.9
|
||||
* Also incorporates [[CanPut]] ECMA-262 v5, 8.12.4
|
||||
*
|
||||
* @return ecma value
|
||||
@@ -1361,6 +1436,13 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
{
|
||||
if (ecma_is_property_writable (*property_p))
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (ecma_make_object_value (object_p) != receiver)
|
||||
{
|
||||
return ecma_op_object_put_apply_receiver (receiver, property_name_p, value, is_throw);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/* There is no need for special casing arrays here because changing the
|
||||
* value of an existing property never changes the length of an array. */
|
||||
ecma_named_data_property_assign_value (object_p,
|
||||
@@ -1389,6 +1471,17 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
ecma_property_ref_t property_ref = { NULL };
|
||||
ecma_object_t *proto_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
|
||||
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
|
||||
if (ECMA_OBJECT_IS_PROXY (proto_p))
|
||||
{
|
||||
return ecma_op_object_put_with_receiver (proto_p,
|
||||
property_name_p,
|
||||
value,
|
||||
receiver,
|
||||
is_throw);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
|
||||
|
||||
ecma_property_t inherited_property = ecma_op_object_get_property (proto_p,
|
||||
property_name_p,
|
||||
&property_ref,
|
||||
@@ -1445,6 +1538,10 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
return ecma_op_object_put_apply_receiver (receiver, property_name_p, value, is_throw);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
ecma_property_value_t *new_prop_value_p;
|
||||
new_prop_value_p = ecma_create_named_data_property (object_p,
|
||||
property_name_p,
|
||||
|
||||
@@ -496,6 +496,12 @@
|
||||
VM_OC_MOV_IDENT | VM_OC_GET_STACK | VM_OC_PUT_IDENT) \
|
||||
CBC_OPCODE (CBC_ASSIGN_LET_CONST, CBC_HAS_LITERAL_ARG, -1, \
|
||||
VM_OC_ASSIGN_LET_CONST | VM_OC_GET_STACK) \
|
||||
CBC_OPCODE (CBC_ASSIGN_SUPER, CBC_NO_FLAG, -3, \
|
||||
VM_OC_ASSIGN_SUPER) \
|
||||
CBC_OPCODE (CBC_ASSIGN_SUPER_PUSH_RESULT, CBC_NO_FLAG, -2, \
|
||||
VM_OC_ASSIGN_SUPER | VM_OC_PUT_STACK) \
|
||||
CBC_OPCODE (CBC_ASSIGN_SUPER_BLOCK, CBC_NO_FLAG, -3, \
|
||||
VM_OC_ASSIGN_SUPER | VM_OC_PUT_BLOCK) \
|
||||
\
|
||||
/* Last opcode (not a real opcode). */ \
|
||||
CBC_OPCODE (CBC_END, CBC_NO_FLAG, 0, \
|
||||
@@ -616,11 +622,15 @@
|
||||
VM_OC_PUSH_SUPER_CONSTRUCTOR) \
|
||||
CBC_OPCODE (CBC_EXT_PUSH_SUPER_PROP, CBC_NO_FLAG, 0, \
|
||||
VM_OC_SUPER_REFERENCE | VM_OC_GET_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SUPER_PROP_CALL_REFERENCE, CBC_NO_FLAG, 2, \
|
||||
CBC_OPCODE (CBC_EXT_SUPER_PROP_REFERENCE, CBC_NO_FLAG, 2, \
|
||||
VM_OC_SUPER_REFERENCE | VM_OC_GET_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 1, \
|
||||
VM_OC_SUPER_REFERENCE | VM_OC_GET_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_CALL_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
|
||||
CBC_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_REFERENCE, CBC_HAS_LITERAL_ARG, 3, \
|
||||
VM_OC_SUPER_REFERENCE | VM_OC_GET_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE, CBC_NO_FLAG, 1, \
|
||||
VM_OC_SUPER_REFERENCE | VM_OC_GET_STACK) \
|
||||
CBC_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE, CBC_HAS_LITERAL_ARG, 2, \
|
||||
VM_OC_SUPER_REFERENCE | VM_OC_GET_LITERAL) \
|
||||
CBC_OPCODE (CBC_EXT_RESOLVE_LEXICAL_THIS, CBC_NO_FLAG, 1, \
|
||||
VM_OC_RESOLVE_LEXICAL_THIS | VM_OC_PUT_STACK) \
|
||||
|
||||
@@ -221,6 +221,15 @@ parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
|
||||
/* Invalid LeftHandSide expression. */
|
||||
if (opcode == CBC_DELETE_PUSH_RESULT)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL)
|
||||
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
|
||||
{
|
||||
parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
|
||||
parser_emit_cbc (context_p, CBC_POP);
|
||||
return;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
parser_emit_cbc (context_p, CBC_POP);
|
||||
parser_emit_cbc (context_p, CBC_PUSH_TRUE);
|
||||
return;
|
||||
@@ -1904,12 +1913,12 @@ parser_process_unary_expression (parser_context_t *context_p, /**< context */
|
||||
}
|
||||
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_CALL_REFERENCE);
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_REFERENCE);
|
||||
opcode = CBC_CALL_PROP;
|
||||
}
|
||||
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_CALL_REFERENCE);
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_REFERENCE);
|
||||
opcode = CBC_CALL_PROP;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
@@ -2180,13 +2189,6 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**<
|
||||
* assignment, since it has multiple forms depending on the
|
||||
* previous instruction. */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
|
||||
{
|
||||
context_p->last_cbc_opcode = CBC_PUSH_PROP_THIS_LITERAL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode)
|
||||
&& context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
|
||||
{
|
||||
@@ -2265,6 +2267,18 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**<
|
||||
parser_stack_push_uint8 (context_p, CBC_ASSIGN);
|
||||
}
|
||||
}
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
|
||||
parser_stack_push_uint8 (context_p, CBC_ASSIGN_SUPER);
|
||||
}
|
||||
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
|
||||
{
|
||||
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE);
|
||||
parser_stack_push_uint8 (context_p, CBC_ASSIGN_SUPER);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
else
|
||||
{
|
||||
/* Invalid LeftHandSide expression. */
|
||||
|
||||
+81
-3
@@ -1184,6 +1184,19 @@ opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, /**< current vm stac
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
ecma_value_t *stack_top_p = *vm_stack_top_p;
|
||||
|
||||
if (opcode >= CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE)
|
||||
{
|
||||
JERRY_ASSERT (opcode == CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE
|
||||
|| opcode == CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
|
||||
*stack_top_p++ = parent;
|
||||
*stack_top_p++ = ecma_copy_value (prop_name);
|
||||
*vm_stack_top_p = stack_top_p;
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
ecma_object_t *parent_p = ecma_get_object_from_value (parent);
|
||||
ecma_string_t *prop_name_p = ecma_op_to_prop_name (prop_name);
|
||||
|
||||
@@ -1202,9 +1215,7 @@ opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, /**< current vm stac
|
||||
return result;
|
||||
}
|
||||
|
||||
ecma_value_t *stack_top_p = *vm_stack_top_p;
|
||||
|
||||
if (opcode == CBC_EXT_SUPER_PROP_LITERAL_CALL_REFERENCE || opcode == CBC_EXT_SUPER_PROP_CALL_REFERENCE)
|
||||
if (opcode == CBC_EXT_SUPER_PROP_LITERAL_REFERENCE || opcode == CBC_EXT_SUPER_PROP_REFERENCE)
|
||||
{
|
||||
*stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
|
||||
*stack_top_p++ = ECMA_VALUE_UNDEFINED;
|
||||
@@ -1215,6 +1226,73 @@ opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, /**< current vm stac
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* opfunc_form_super_reference */
|
||||
|
||||
/**
|
||||
* Assignment operation for SuperRefence base
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
opfunc_assign_super_reference (ecma_value_t **vm_stack_top_p, /**< vm stack top */
|
||||
vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
uint32_t opcode_data) /**< opcode data to store the result */
|
||||
{
|
||||
ecma_value_t *stack_top_p = *vm_stack_top_p;
|
||||
|
||||
ecma_value_t base_obj = ecma_op_to_object (stack_top_p[-3]);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (base_obj))
|
||||
{
|
||||
return base_obj;
|
||||
}
|
||||
|
||||
ecma_object_t *base_obj_p = ecma_get_object_from_value (base_obj);
|
||||
ecma_string_t *prop_name_p = ecma_op_to_prop_name (stack_top_p[-2]);
|
||||
|
||||
if (prop_name_p == NULL)
|
||||
{
|
||||
ecma_deref_object (base_obj_p);
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
bool is_strict = (frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||
|
||||
ecma_value_t result = ecma_op_object_put_with_receiver (base_obj_p,
|
||||
prop_name_p,
|
||||
stack_top_p[-1],
|
||||
frame_ctx_p->this_binding,
|
||||
is_strict);
|
||||
|
||||
ecma_deref_ecma_string (prop_name_p);
|
||||
ecma_deref_object (base_obj_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
for (int32_t i = 1; i <= 3; i++)
|
||||
{
|
||||
ecma_free_value (stack_top_p[-i]);
|
||||
}
|
||||
|
||||
stack_top_p -= 3;
|
||||
|
||||
if (opcode_data & VM_OC_PUT_STACK)
|
||||
{
|
||||
*stack_top_p++ = result;
|
||||
}
|
||||
else if (opcode_data & VM_OC_PUT_BLOCK)
|
||||
{
|
||||
ecma_fast_free_value (frame_ctx_p->block_result);
|
||||
frame_ctx_p->block_result = result;
|
||||
}
|
||||
|
||||
*vm_stack_top_p = stack_top_p;
|
||||
|
||||
return result;
|
||||
} /* opfunc_assign_super_reference */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
|
||||
@@ -137,6 +137,9 @@ opfunc_finalize_class (vm_frame_ctx_t *frame_ctx_p, ecma_value_t **vm_stack_top_
|
||||
ecma_value_t
|
||||
opfunc_form_super_reference (ecma_value_t **vm_stack_top_p, vm_frame_ctx_t *frame_ctx_p, ecma_value_t prop_name,
|
||||
uint8_t opcode);
|
||||
|
||||
ecma_value_t
|
||||
opfunc_assign_super_reference (ecma_value_t **vm_stack_top_p, vm_frame_ctx_t *frame_ctx_p, uint32_t opcode_data);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
|
||||
@@ -2012,6 +2012,16 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
result = ecma_op_check_object_coercible (stack_top_p[-1]);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case VM_OC_ASSIGN_SUPER:
|
||||
{
|
||||
result = opfunc_assign_super_reference (&stack_top_p, frame_ctx_p, opcode_data);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
|
||||
@@ -266,6 +266,7 @@ typedef enum
|
||||
VM_OC_GET_TEMPLATE_OBJECT, /**< GetTemplateObject operation */
|
||||
VM_OC_PUSH_NEW_TARGET, /**< push new.target onto the stack */
|
||||
VM_OC_REQUIRE_OBJECT_COERCIBLE,/**< RequireObjectCoercible opretaion */
|
||||
VM_OC_ASSIGN_SUPER, /**< assign super reference */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
VM_OC_NONE, /**< a special opcode for unsupported byte codes */
|
||||
} vm_oc_types;
|
||||
@@ -323,6 +324,7 @@ typedef enum
|
||||
VM_OC_GET_TEMPLATE_OBJECT = VM_OC_NONE, /**< GetTemplateObject operation */
|
||||
VM_OC_PUSH_NEW_TARGET = VM_OC_NONE, /**< push new.target onto the stack */
|
||||
VM_OC_REQUIRE_OBJECT_COERCIBLE = VM_OC_NONE,/**< RequireObjectCoercible opretaion */
|
||||
VM_OC_ASSIGN_SUPER = VM_OC_NONE, /**< assign super reference */
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
|
||||
VM_OC_UNUSED = VM_OC_NONE /**< placeholder if the list is empty */
|
||||
|
||||
@@ -43,7 +43,7 @@ assert(monster.foo === "foo");
|
||||
var target = { foo: "foo"};
|
||||
var handler = {
|
||||
set: function(obj, prop, value) {
|
||||
obj[prop] = "";
|
||||
obj[prop] = "";
|
||||
}
|
||||
};
|
||||
var proxy = new Proxy(target, handler);
|
||||
@@ -58,6 +58,7 @@ var handler = {};
|
||||
var proxy = new Proxy(target, handler);
|
||||
|
||||
// test when property does not exist on target
|
||||
/* TODO: Enable these tests when Proxy.[[GetOwnProperty]] has been implemented
|
||||
for (var p of properties) {
|
||||
proxy.p = 42;
|
||||
assert(target.p === 42);
|
||||
@@ -73,7 +74,7 @@ for (var p of properties) {
|
||||
proxy.p = 42;
|
||||
assert(target.p === 42);
|
||||
}
|
||||
|
||||
*/
|
||||
// test when target is a proxy
|
||||
var target = {};
|
||||
var handler = {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright JS Foundation and other contributors, http://js.foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
var setterCalled = false;
|
||||
|
||||
class Base {
|
||||
func () {
|
||||
return 5;
|
||||
}
|
||||
funcArrow () {
|
||||
return () => 5;
|
||||
}
|
||||
["com" + "puted"] () {
|
||||
return 10;
|
||||
}
|
||||
get getter () {
|
||||
return 6;
|
||||
}
|
||||
set setter (a) {
|
||||
setterCalled = true;
|
||||
}
|
||||
getSuperValueOf() {
|
||||
return super.valueOf;
|
||||
}
|
||||
}
|
||||
|
||||
class Derived extends Base {
|
||||
func () {
|
||||
return super.func();
|
||||
}
|
||||
funcArrow () {
|
||||
return () => super.func();
|
||||
}
|
||||
["com" + "puted"] () {
|
||||
return super["com" + "puted"]();
|
||||
}
|
||||
get getter () {
|
||||
return super.getter;
|
||||
}
|
||||
set setter (a) {
|
||||
super.setter = a;
|
||||
}
|
||||
deleteSuperReference () {
|
||||
delete super.a;
|
||||
}
|
||||
}
|
||||
|
||||
var derived = new Derived;
|
||||
var base = new Base;
|
||||
|
||||
assert (derived.func() === 5);
|
||||
assert (derived.funcArrow()() === 5);
|
||||
assert (derived.computed() === 10);
|
||||
assert (derived.getter === 6);
|
||||
derived.setter = 7;
|
||||
assert (setterCalled === true);
|
||||
assert (base.getSuperValueOf() === Object.prototype.valueOf);
|
||||
|
||||
try {
|
||||
derived.deleteSuperReference();
|
||||
assert (false);
|
||||
} catch (e) {
|
||||
assert (e instanceof ReferenceError);
|
||||
}
|
||||
Reference in New Issue
Block a user