Properly handle primitive arguments in Object methods (#3342)

ES2015 allows primitive arguments for most of the Object built-ins.
This change implements handling for these arguments in affected methods.

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
Dániel Bátyai
2019-11-22 12:48:10 +01:00
committed by Robert Fancsik
parent d006f068f4
commit 3bf2bc50bc
10 changed files with 317 additions and 171 deletions
@@ -40,23 +40,32 @@
enum enum
{ {
ECMA_OBJECT_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1, ECMA_OBJECT_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1,
ECMA_OBJECT_ROUTINE_DEFINE_PROPERTY,
ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR,
ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES,
ECMA_OBJECT_ROUTINE_CREATE, ECMA_OBJECT_ROUTINE_CREATE,
ECMA_OBJECT_ROUTINE_SEAL, ECMA_OBJECT_ROUTINE_IS,
ECMA_OBJECT_ROUTINE_FREEZE, ECMA_OBJECT_ROUTINE_SET_PROTOTYPE_OF,
ECMA_OBJECT_ROUTINE_PREVENT_EXTENSIONS,
ECMA_OBJECT_ROUTINE_IS_SEALED, /* These should be in this order. */
ECMA_OBJECT_ROUTINE_IS_FROZEN, ECMA_OBJECT_ROUTINE_DEFINE_PROPERTY,
ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE, ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES,
/* These should be in this order. */
ECMA_OBJECT_ROUTINE_ASSIGN,
ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR,
ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES, ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES,
ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS, ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS,
ECMA_OBJECT_ROUTINE_KEYS,
ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF, ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF,
ECMA_OBJECT_ROUTINE_SET_PROTOTYPE_OF, ECMA_OBJECT_ROUTINE_KEYS,
ECMA_OBJECT_ROUTINE_ASSIGN,
ECMA_OBJECT_ROUTINE_IS, /* These should be in this order. */
ECMA_OBJECT_ROUTINE_FREEZE,
ECMA_OBJECT_ROUTINE_PREVENT_EXTENSIONS,
ECMA_OBJECT_ROUTINE_SEAL,
/* These should be in this order. */
ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE,
ECMA_OBJECT_ROUTINE_IS_FROZEN,
ECMA_OBJECT_ROUTINE_IS_SEALED,
}; };
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-object.inc.h" #define BUILTIN_INC_HEADER_NAME "ecma-builtin-object.inc.h"
@@ -125,47 +134,18 @@ ecma_builtin_object_dispatch_construct (const ecma_value_t *arguments_list_p, /*
* Returned value must be freed with ecma_free_value. * Returned value must be freed with ecma_free_value.
*/ */
ecma_value_t ecma_value_t
ecma_builtin_object_object_get_prototype_of (ecma_value_t arg) /**< routine's argument */ ecma_builtin_object_object_get_prototype_of (ecma_object_t *obj_p) /**< routine's argument */
{ {
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
bool was_object = ecma_is_value_object (arg);
/* 1. */
if (!was_object)
{
#if ENABLED (JERRY_ES2015_BUILTIN)
arg = ecma_op_to_object (arg);
if (ECMA_IS_VALUE_ERROR (arg))
{
return arg;
}
#else /* !ENABLED (JERRY_ES2015_BUILTIN) */
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
}
/* 2. */
ecma_object_t *obj_p = ecma_get_object_from_value (arg);
jmem_cpointer_t prototype_cp = obj_p->u2.prototype_cp; jmem_cpointer_t prototype_cp = obj_p->u2.prototype_cp;
if (prototype_cp != JMEM_CP_NULL) if (prototype_cp != JMEM_CP_NULL)
{ {
ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp); ecma_object_t *prototype_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, prototype_cp);
ret_value = ecma_make_object_value (prototype_p);
ecma_ref_object (prototype_p); ecma_ref_object (prototype_p);
} return ecma_make_object_value (prototype_p);
else
{
ret_value = ECMA_VALUE_NULL;
} }
#if ENABLED (JERRY_ES2015_BUILTIN) return ECMA_VALUE_NULL;
if (!was_object)
{
ecma_deref_object (obj_p);
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */
return ret_value;
} /* ecma_builtin_object_object_get_prototype_of */ } /* ecma_builtin_object_object_get_prototype_of */
#if ENABLED (JERRY_ES2015_BUILTIN) #if ENABLED (JERRY_ES2015_BUILTIN)
@@ -772,31 +752,14 @@ ecma_builtin_object_object_define_property (ecma_object_t *obj_p, /**< routine's
* Returned value must be freed with ecma_free_value. * Returned value must be freed with ecma_free_value.
*/ */
static ecma_value_t static ecma_value_t
ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< arguments list */ ecma_builtin_object_object_assign (ecma_object_t *target_p, /**< target object */
const ecma_value_t arguments_list_p[], /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */ ecma_length_t arguments_list_len) /**< number of arguments */
{ {
ecma_value_t target = arguments_list_len > 0 ? arguments_list_p[0] : ECMA_VALUE_UNDEFINED;
/* 1. */
ecma_value_t to_value = ecma_op_to_object (target);
if (ECMA_IS_VALUE_ERROR (to_value))
{
return to_value;
}
ecma_object_t *to_obj_p = ecma_get_object_from_value (to_value);
/* 2. */
if (arguments_list_len == 1)
{
return to_value;
}
ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 4-5. */ /* 4-5. */
for (uint32_t i = 1; i < arguments_list_len && ecma_is_value_empty (ret_value); i++) for (uint32_t i = 0; i < arguments_list_len && ecma_is_value_empty (ret_value); i++)
{ {
ecma_value_t next_source = arguments_list_p[i]; ecma_value_t next_source = arguments_list_p[i];
@@ -848,7 +811,7 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
else else
{ {
/* 5.c.iii.3 */ /* 5.c.iii.3 */
ecma_value_t status = ecma_op_object_put (to_obj_p, property_name_p, prop_value, true); ecma_value_t status = ecma_op_object_put (target_p, property_name_p, prop_value, true);
/* 5.c.iii.4 */ /* 5.c.iii.4 */
if (ECMA_IS_VALUE_ERROR (status)) if (ECMA_IS_VALUE_ERROR (status))
@@ -869,10 +832,10 @@ ecma_builtin_object_object_assign (const ecma_value_t arguments_list_p[], /**< a
/* 6. */ /* 6. */
if (ecma_is_value_empty (ret_value)) if (ecma_is_value_empty (ret_value))
{ {
return to_value; ecma_ref_object (target_p);
return ecma_make_object_value (target_p);
} }
ecma_deref_object (to_obj_p);
return ret_value; return ret_value;
} /* ecma_builtin_object_object_assign */ } /* ecma_builtin_object_object_assign */
#endif /* ENABLED (JERRY_ES2015_BUILTIN) */ #endif /* ENABLED (JERRY_ES2015_BUILTIN) */
@@ -924,19 +887,11 @@ ecma_builtin_object_dispatch_routine (uint16_t builtin_routine_id, /**< built-in
{ {
return ecma_builtin_object_object_create (arg1, arg2); return ecma_builtin_object_object_create (arg1, arg2);
} }
case ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF:
{
return ecma_builtin_object_object_get_prototype_of (arg1);
}
#if ENABLED (JERRY_ES2015_BUILTIN) #if ENABLED (JERRY_ES2015_BUILTIN)
case ECMA_OBJECT_ROUTINE_SET_PROTOTYPE_OF: case ECMA_OBJECT_ROUTINE_SET_PROTOTYPE_OF:
{ {
return ecma_builtin_object_object_set_prototype_of (arg1, arg2); return ecma_builtin_object_object_set_prototype_of (arg1, arg2);
} }
case ECMA_OBJECT_ROUTINE_ASSIGN:
{
return ecma_builtin_object_object_assign (arguments_list_p, arguments_number);
}
case ECMA_OBJECT_ROUTINE_IS: case ECMA_OBJECT_ROUTINE_IS:
{ {
return ecma_builtin_object_object_is (arg1, arg2); return ecma_builtin_object_object_is (arg1, arg2);
@@ -948,83 +903,169 @@ ecma_builtin_object_dispatch_routine (uint16_t builtin_routine_id, /**< built-in
} }
} }
ecma_object_t *obj_p;
#if !ENABLED (JERRY_ES2015)
if (!ecma_is_value_object (arg1)) if (!ecma_is_value_object (arg1))
{ {
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object.")); return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
} }
#endif /* !ENABLED (JERRY_ES2015) */
ecma_object_t *obj_p = ecma_get_object_from_value (arg1); if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES)
if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR)
{ {
ecma_string_t *prop_name_p = ecma_op_to_prop_name (arg2); #if ENABLED (JERRY_ES2015)
if (!ecma_is_value_object (arg1))
if (prop_name_p == NULL)
{ {
return ECMA_VALUE_ERROR; return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
} }
#endif /* ENABLED (JERRY_ES2015) */
ecma_value_t ret_value; obj_p = ecma_get_object_from_value (arg1);
if (builtin_routine_id == ECMA_OBJECT_ROUTINE_DEFINE_PROPERTY) if (builtin_routine_id == ECMA_OBJECT_ROUTINE_DEFINE_PROPERTY)
{ {
ret_value = ecma_builtin_object_object_define_property (obj_p, prop_name_p, arguments_list_p[2]); ecma_string_t *prop_name_p = ecma_op_to_prop_name (arg2);
}
else if (prop_name_p == NULL)
{ {
JERRY_ASSERT (builtin_routine_id == ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR); return ECMA_VALUE_ERROR;
ret_value = ecma_builtin_object_object_get_own_property_descriptor (obj_p, prop_name_p); }
ecma_value_t result = ecma_builtin_object_object_define_property (obj_p, prop_name_p, arguments_list_p[2]);
ecma_deref_ecma_string (prop_name_p);
return result;
} }
ecma_deref_ecma_string (prop_name_p); JERRY_ASSERT (builtin_routine_id == ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES);
return ret_value; return ecma_builtin_object_object_define_properties (obj_p, arg2);
} }
else if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_KEYS)
switch (builtin_routine_id)
{ {
case ECMA_OBJECT_ROUTINE_SEAL:
{
return ecma_builtin_object_object_seal (obj_p);
}
case ECMA_OBJECT_ROUTINE_FREEZE:
{
return ecma_builtin_object_object_freeze (obj_p);
}
case ECMA_OBJECT_ROUTINE_PREVENT_EXTENSIONS:
{
return ecma_builtin_object_object_prevent_extensions (obj_p);
}
case ECMA_OBJECT_ROUTINE_IS_SEALED:
case ECMA_OBJECT_ROUTINE_IS_FROZEN:
{
return ecma_builtin_object_frozen_or_sealed_helper (obj_p,
builtin_routine_id);
}
case ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE:
{
return ecma_builtin_object_object_is_extensible (obj_p);
}
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES:
{
return ecma_builtin_object_object_get_own_property_names (obj_p);
}
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS: ecma_value_t object = ecma_op_to_object (arg1);
if (ECMA_IS_VALUE_ERROR (object))
{ {
return ecma_builtin_object_object_get_own_property_symbols (obj_p); return object;
}
obj_p = ecma_get_object_from_value (object);
#else /* !ENABLED (JERRY_ES2015) */
obj_p = ecma_get_object_from_value (arg1);
#endif /* ENABLED (JERRY_ES2015) */
ecma_value_t result;
switch (builtin_routine_id)
{
case ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF:
{
result = ecma_builtin_object_object_get_prototype_of (obj_p);
break;
}
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_NAMES:
{
result = ecma_builtin_object_object_get_own_property_names (obj_p);
break;
}
#if ENABLED (JERRY_ES2015)
case ECMA_OBJECT_ROUTINE_ASSIGN:
{
result = ecma_builtin_object_object_assign (obj_p, arguments_list_p + 1, arguments_number - 1);
break;
}
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_SYMBOLS:
{
result = ecma_builtin_object_object_get_own_property_symbols (obj_p);
break;
}
#endif /* ENABLED (JERRY_ES2015) */
case ECMA_OBJECT_ROUTINE_KEYS:
{
result = ecma_builtin_object_object_keys (obj_p);
break;
}
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR:
{
ecma_string_t *prop_name_p = ecma_op_to_prop_name (arg2);
if (prop_name_p == NULL)
{
result = ECMA_VALUE_ERROR;
break;
}
result = ecma_builtin_object_object_get_own_property_descriptor (obj_p, prop_name_p);
ecma_deref_ecma_string (prop_name_p);
break;
}
default:
{
JERRY_UNREACHABLE ();
}
}
#if ENABLED (JERRY_ES2015)
ecma_deref_object (obj_p);
#endif /* ENABLED (JERRY_ES2015) */
return result;
}
else if (builtin_routine_id <= ECMA_OBJECT_ROUTINE_SEAL)
{
#if ENABLED (JERRY_ES2015)
if (!ecma_is_value_object (arg1))
{
return arg1;
} }
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
case ECMA_OBJECT_ROUTINE_KEYS:
obj_p = ecma_get_object_from_value (arg1);
switch (builtin_routine_id)
{ {
return ecma_builtin_object_object_keys (obj_p); case ECMA_OBJECT_ROUTINE_SEAL:
{
return ecma_builtin_object_object_seal (obj_p);
}
case ECMA_OBJECT_ROUTINE_FREEZE:
{
return ecma_builtin_object_object_freeze (obj_p);
}
case ECMA_OBJECT_ROUTINE_PREVENT_EXTENSIONS:
{
return ecma_builtin_object_object_prevent_extensions (obj_p);
}
default:
{
JERRY_UNREACHABLE ();
}
} }
case ECMA_OBJECT_ROUTINE_DEFINE_PROPERTIES: }
else
{
JERRY_ASSERT (builtin_routine_id <= ECMA_OBJECT_ROUTINE_IS_SEALED);
#if ENABLED (JERRY_ES2015)
if (!ecma_is_value_object (arg1))
{ {
return ecma_builtin_object_object_define_properties (obj_p, arg2); return ecma_make_boolean_value (builtin_routine_id != ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE);
} }
default: #endif /* ENABLED (JERRY_ES2015) */
obj_p = ecma_get_object_from_value (arg1);
switch (builtin_routine_id)
{ {
JERRY_UNREACHABLE (); case ECMA_OBJECT_ROUTINE_IS_SEALED:
case ECMA_OBJECT_ROUTINE_IS_FROZEN:
{
return ecma_builtin_object_frozen_or_sealed_helper (obj_p,
builtin_routine_id);
}
case ECMA_OBJECT_ROUTINE_IS_EXTENSIBLE:
{
return ecma_builtin_object_object_is_extensible (obj_p);
}
default:
{
JERRY_UNREACHABLE ();
}
} }
} }
} /* ecma_builtin_object_dispatch_routine */ } /* ecma_builtin_object_dispatch_routine */
@@ -15,7 +15,7 @@
#ifndef ECMA_BUILTIN_OBJECT_H #ifndef ECMA_BUILTIN_OBJECT_H
#define ECMA_BUILTIN_OBJECT_H #define ECMA_BUILTIN_OBJECT_H
ecma_value_t ecma_builtin_object_object_get_prototype_of (ecma_value_t arg); ecma_value_t ecma_builtin_object_object_get_prototype_of (ecma_object_t *obj_p);
ecma_value_t ecma_builtin_object_object_set_prototype_of (ecma_value_t arg1, ecma_value_t ecma_builtin_object_object_set_prototype_of (ecma_value_t arg1,
ecma_value_t arg2); ecma_value_t arg2);
@@ -87,7 +87,7 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i
{ {
case ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF_UL: case ECMA_REFLECT_OBJECT_GET_PROTOTYPE_OF_UL:
{ {
return ecma_builtin_object_object_get_prototype_of (arguments_list[0]); return ecma_builtin_object_object_get_prototype_of (ecma_get_object_from_value (arguments_list[0]));
} }
case ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF_UL: case ECMA_REFLECT_OBJECT_SET_PROTOTYPE_OF_UL:
{ {
@@ -109,11 +109,3 @@ assert (props.indexOf(foo2) !== -1);
assert (props.length === 2); assert (props.length === 2);
assert (Object.getOwnPropertyDescriptor (object, foo).enumerable === true); assert (Object.getOwnPropertyDescriptor (object, foo).enumerable === true);
assert (Object.getOwnPropertyDescriptor (object, foo2).enumerable === false); assert (Object.getOwnPropertyDescriptor (object, foo2).enumerable === false);
// Test non-object argument
try {
Object.getOwnPropertySymbols ('hello');
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
+48
View File
@@ -0,0 +1,48 @@
// 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.
assert (JSON.stringify (Object.getOwnPropertyNames("hello")) === '["0","1","2","3","4","length"]');
var n = Object.assign(42, {a: "str"});
assert (n instanceof Number);
assert (n.valueOf() === 42);
assert (n.a === "str");
assert (JSON.stringify (Object.getOwnPropertySymbols("hello")) === '[]');
assert (JSON.stringify (Object.keys("str")) === '["0","1","2"]');
var d = Object.getOwnPropertyDescriptor("hello", '1');
assert (d.value === "e");
assert (d.writable === false);
assert (d.enumerable === true);
assert (d.configurable === false);
assert (Object.seal(42) === 42);
assert (Object.seal(undefined) === undefined);
assert (Object.isSealed(42) === true);
assert (Object.isSealed(undefined) === true);
assert (Object.freeze(42) === 42);
assert (Object.freeze(undefined) === undefined);
assert (Object.isFrozen(42) === true);
assert (Object.isFrozen(undefined) === true);
assert (Object.preventExtensions(42) === 42);
assert (Object.preventExtensions(undefined) === undefined);
assert (Object.isExtensible(42) === false);
assert (Object.isExtensible(undefined) === false);
+89
View File
@@ -0,0 +1,89 @@
// 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.
try {
Object.getOwnPropertyNames("hello");
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.preventExtensions(42);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.isExtensible(42);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.seal(42);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.isSealed(42);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.freeze(42);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.isFrozen(42);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try {
Object.keys("hello");
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try {
Object.getOwnPropertyNames("hello");
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try {
Object.getOwnPropertyDescriptor("hello", '1');
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
+9
View File
@@ -68,3 +68,12 @@ try {
} catch (err) { } catch (err) {
assert (err === 234); assert (err === 234);
} }
try {
Object.defineProperty(42, "prop", {
set: undefined
});
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
@@ -62,11 +62,3 @@ assert (props.indexOf("prop") !== -1);
assert (props.indexOf("method") !== -1); assert (props.indexOf("method") !== -1);
assert (props.length === 2); assert (props.length === 2);
// Test non-object argument
try {
Object.getOwnPropertyNames("hello");
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
-17
View File
@@ -20,23 +20,6 @@ assert (Object.isExtensible(empty) === true);
Object.preventExtensions(empty); Object.preventExtensions(empty);
assert(Object.isExtensible(empty) === false); assert(Object.isExtensible(empty) === false);
// Call on undefined should throw TypeError.
try
{
Object.isExtensible(undefined);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
try
{
Object.preventExtensions(undefined);
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
// Sealed objects are by definition non-extensible. // Sealed objects are by definition non-extensible.
var sealed = Object.seal({}); var sealed = Object.seal({});
assert (Object.isExtensible(sealed) === false); assert (Object.isExtensible(sealed) === false);
-8
View File
@@ -61,14 +61,6 @@ assert (props.indexOf("prop") !== -1);
assert (props.indexOf("method") !== -1); assert (props.indexOf("method") !== -1);
assert (props.length === 2); assert (props.length === 2);
// Test non-object argument
try {
Object.keys("hello");
assert (false);
} catch (e) {
assert (e instanceof TypeError);
}
var o = {}; var o = {};
Object.defineProperty(o, 'a', { Object.defineProperty(o, 'a', {