Update "arguments" and "caller" properties of function object to conform ES6 changes (#3530)

This patch resolves #3393.

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik
2020-01-23 15:53:37 +01:00
committed by GitHub
parent b7a2a153aa
commit 3c5fb342be
9 changed files with 98 additions and 4 deletions
@@ -48,6 +48,14 @@ ROUTINE (LIT_MAGIC_STRING_BIND, ECMA_FUNCTION_PROTOTYPE_BIND, NON_FIXED, 1)
* the property attributes are: { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
*/
ROUTINE_WITH_FLAGS (LIT_GLOBAL_SYMBOL_HAS_INSTANCE, ECMA_FUNCTION_PROTOTYPE_SYMBOL_HAS_INSTANCE, 1, 1, 0 /* flags */)
ACCESSOR_BUILTIN_FUNCTION (LIT_MAGIC_STRING_ARGUMENTS,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
ACCESSOR_BUILTIN_FUNCTION (LIT_MAGIC_STRING_CALLER,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_BUILTIN_ID_TYPE_ERROR_THROWER,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ES2015) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -33,6 +33,10 @@
#ifndef INTRINSIC_PROPERTY
#define INTRINSIC_PROPERTY(name, magic_string_id)
#endif /* !INTRINSIC_PROPERTY */
#ifndef ACCESSOR_BUILTIN_FUNCTION_OBJECT
#define ACCESSOR_BUILTIN_FUNCTION_OBJECT(name, getter_builtin_id, setter_builtin_id, prop_attributes)
#endif /* !ACCESSOR_BUILTIN_FUNCTION_OBJECT */
#endif /* ENABLED (JERRY_ES2015) */
#ifndef OBJECT_VALUE
@@ -19,6 +19,7 @@
#if ENABLED (JERRY_ES2015)
#undef SYMBOL_VALUE
#undef INTRINSIC_PROPERTY
#undef ACCESSOR_BUILTIN_FUNCTION_OBJECT
#endif /* ENABLED (JERRY_ES2015) */
#undef OBJECT_VALUE
#undef ROUTINE
@@ -189,6 +189,13 @@ const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \
magic_string_id \
},
#define ACCESSOR_BUILTIN_FUNCTION(name, getter_builtin_id, setter_builtin_id, prop_attributes) \
{ \
name, \
ECMA_BUILTIN_PROPERTY_ACCESSOR_BUILTIN_FUNCTION, \
prop_attributes, \
ECMA_ACCESSOR_READ_WRITE (getter_builtin_id, setter_builtin_id) \
},
#endif /* ENABLED (JERRY_ES2015) */
#define ACCESSOR_READ_WRITE(name, c_getter_name, c_setter_name, prop_attributes) \
{ \
@@ -55,8 +55,8 @@ ecma_builtin_type_error_thrower_dispatch_call (const ecma_value_t *arguments_lis
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
/* The object should throw TypeError */
return ecma_raise_type_error (ECMA_ERR_MSG (""));
return ecma_raise_type_error (ECMA_ERR_MSG ("'caller', 'callee', and 'arguments' properties may not be accessed"
" on strict mode functions or the arguments objects for calls to them"));
} /* ecma_builtin_type_error_thrower_dispatch_call */
/**
@@ -73,8 +73,7 @@ ecma_builtin_type_error_thrower_dispatch_construct (const ecma_value_t *argument
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
/* The object is not a constructor */
return ecma_raise_type_error (ECMA_ERR_MSG (""));
return ecma_builtin_type_error_thrower_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_type_error_thrower_dispatch_construct */
/**
@@ -34,6 +34,8 @@ typedef enum
#if ENABLED (JERRY_ES2015)
ECMA_BUILTIN_PROPERTY_SYMBOL, /**< symbol value property */
ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY, /**< intrinsic routine property */
ECMA_BUILTIN_PROPERTY_ACCESSOR_BUILTIN_FUNCTION, /**< full accessor property with builtin function object
getter/setter pair */
#endif /* ENABLED (JERRY_ES2015) */
ECMA_BUILTIN_PROPERTY_OBJECT, /**< builtin object property */
ECMA_BUILTIN_PROPERTY_ROUTINE, /**< routine property */
@@ -814,6 +814,17 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
(lit_magic_string_id_t) curr_property_p->value);
break;
}
case ECMA_BUILTIN_PROPERTY_ACCESSOR_BUILTIN_FUNCTION:
{
is_accessor = true;
uint16_t getter_id = ECMA_ACCESSOR_READ_WRITE_GET_GETTER_ID (curr_property_p->value);
uint16_t setter_id = ECMA_ACCESSOR_READ_WRITE_GET_SETTER_ID (curr_property_p->value);
getter_p = ecma_builtin_get (getter_id);
setter_p = ecma_builtin_get (setter_id);
ecma_ref_object (getter_p);
ecma_ref_object (setter_p);
break;
}
#endif /* ENABLED (JERRY_ES2015) */
case ECMA_BUILTIN_PROPERTY_OBJECT:
{
@@ -1643,6 +1643,19 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
}
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015)
if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
{
ecma_property_t *value_prop_p;
/* The property_name_p argument contans the name. */
ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
property_name_p,
ECMA_PROPERTY_FIXED,
&value_prop_p);
value_p->value = ECMA_VALUE_NULL;
return value_prop_p;
}
#else /* !ENABLED (JERRY_ES2015) */
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
{
ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
@@ -1657,6 +1670,8 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
&caller_prop_p);
return caller_prop_p;
}
#endif /* ENABLED (JERRY_ES2015) */
}
return NULL;
@@ -0,0 +1,47 @@
// 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 props = ['arguments', 'caller'];
function f_simple () {
}
function f_strict () {
"use strict";
}
for (let prop of props) {
try {
Function.prototype[prop];
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
assert(f_simple[prop] === null);
try {
f_strict[prop];
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
let desc = Object.getOwnPropertyDescriptor(f_simple, prop);
assert(desc.value === null);
assert(desc.writable === false);
assert(desc.enumerable === false);
assert(desc.configurable === false);
assert(Object.getOwnPropertyDescriptor(f_strict, prop) === undefined);
}