Skip to content

Commit 768a209

Browse files
authored
Implement 'hasOwn' routine of Object object (#4835)
JerryScript-DCO-1.0-Signed-off-by: Csaba Repasi [email protected]
1 parent ce5c849 commit 768a209

File tree

10 files changed

+109
-102
lines changed

10 files changed

+109
-102
lines changed

jerry-core/api/jerryscript.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,28 +3215,8 @@ jerry_object_has_own (const jerry_value_t object, /**< object value */
32153215
ecma_object_t *obj_p = ecma_get_object_from_value (object);
32163216
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (key);
32173217

3218-
#if JERRY_BUILTIN_PROXY
3219-
if (ECMA_OBJECT_IS_PROXY (obj_p))
3220-
{
3221-
ecma_property_descriptor_t prop_desc;
3222-
3223-
ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
3224-
3225-
if (ecma_is_value_true (status))
3226-
{
3227-
ecma_free_property_descriptor (&prop_desc);
3228-
}
3229-
3230-
return jerry_return (status);
3231-
}
3232-
#endif /* JERRY_BUILTIN_PROXY */
3233-
3234-
#if JERRY_BUILTIN_TYPEDARRAY
3235-
return jerry_return (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
3236-
#else /* !JERRY_BUILTIN_TYPEDARRAY */
3237-
return ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p);
3238-
#endif /* JERRY_BUILTIN_TYPEDARRAY */
3239-
} /* jerry_object_has_own */
3218+
return jerry_return (ecma_op_object_has_own_property (obj_p, prop_name_p));
3219+
} /* jerry_has_own_property */
32403220

32413221
/**
32423222
* Checks whether the object has the given internal property.

jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,7 @@ static ecma_value_t
132132
ecma_builtin_object_prototype_object_has_own_property (ecma_object_t *obj_p, /**< this argument */
133133
ecma_string_t *prop_name_p) /**< first argument */
134134
{
135-
#if JERRY_BUILTIN_PROXY
136-
if (ECMA_OBJECT_IS_PROXY (obj_p))
137-
{
138-
ecma_property_descriptor_t prop_desc;
139-
140-
ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (obj_p, prop_name_p, &prop_desc);
141-
142-
if (ecma_is_value_true (status))
143-
{
144-
ecma_free_property_descriptor (&prop_desc);
145-
}
146-
147-
return status;
148-
}
149-
#endif /* JERRY_BUILTIN_PROXY */
150-
151-
return ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p);
135+
return ecma_op_object_has_own_property (obj_p, prop_name_p);
152136
} /* ecma_builtin_object_prototype_object_has_own_property */
153137

154138
/**

jerry-core/ecma/builtin-objects/ecma-builtin-object.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ enum
6363
ECMA_OBJECT_ROUTINE_ASSIGN,
6464
ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR,
6565
ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTORS,
66+
ECMA_OBJECT_ROUTINE_HAS_OWN,
6667
ECMA_OBJECT_ROUTINE_GET_PROTOTYPE_OF,
6768
ECMA_OBJECT_ROUTINE_FROM_ENTRIES,
6869
ECMA_OBJECT_ROUTINE_KEYS,
@@ -1491,6 +1492,20 @@ ecma_builtin_object_dispatch_routine (uint8_t builtin_routine_id, /**< built-in
14911492
break;
14921493
}
14931494
#if JERRY_ESNEXT
1495+
case ECMA_OBJECT_ROUTINE_HAS_OWN:
1496+
{
1497+
ecma_string_t *prop_name_p = ecma_op_to_property_key (arg2);
1498+
1499+
if (prop_name_p == NULL)
1500+
{
1501+
result = ECMA_VALUE_ERROR;
1502+
break;
1503+
}
1504+
1505+
result = ecma_op_object_has_own_property (obj_p, prop_name_p);
1506+
ecma_deref_ecma_string (prop_name_p);
1507+
break;
1508+
}
14941509
case ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTORS:
14951510
{
14961511
result = ecma_builtin_object_object_get_own_property_descriptors (obj_p);

jerry-core/ecma/builtin-objects/ecma-builtin-object.inc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ ROUTINE (LIT_MAGIC_STRING_VALUES, ECMA_OBJECT_ROUTINE_VALUES, 1, 1)
5454
ROUTINE (LIT_MAGIC_STRING_KEYS, ECMA_OBJECT_ROUTINE_KEYS, 1, 1)
5555
ROUTINE (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTOR_UL, ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTOR, 2, 2)
5656
#if JERRY_ESNEXT
57+
ROUTINE (LIT_MAGIC_STRING_HAS_OWN_UL, ECMA_OBJECT_ROUTINE_HAS_OWN, 2, 2)
5758
ROUTINE (LIT_MAGIC_STRING_GET_OWN_PROPERTY_DESCRIPTORS_UL, ECMA_OBJECT_ROUTINE_GET_OWN_PROPERTY_DESCRIPTORS, 1, 1)
5859
ROUTINE (LIT_MAGIC_STRING_OBJECT_FROM_ENTRIES, ECMA_OBJECT_ROUTINE_FROM_ENTRIES, 1, 1)
5960
#endif /* JERRY_ESNEXT */

jerry-core/ecma/operations/ecma-objects.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,6 +3410,35 @@ ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the obje
34103410
return ecma_make_boolean_value (ECMA_PROPERTY_IS_FOUND (property));
34113411
} /* ecma_op_ordinary_object_has_own_property */
34123412

3413+
/**
3414+
* Checks whether an object (excluding prototypes) has a named property. Handles proxy objects too.
3415+
*
3416+
* @return true - if property is found
3417+
* false - otherwise
3418+
*/
3419+
ecma_value_t
3420+
ecma_op_object_has_own_property (ecma_object_t *object_p, /**< the object */
3421+
ecma_string_t *property_name_p) /**< property name */
3422+
{
3423+
#if JERRY_BUILTIN_PROXY
3424+
if (ECMA_OBJECT_IS_PROXY (object_p))
3425+
{
3426+
ecma_property_descriptor_t prop_desc;
3427+
3428+
ecma_value_t status = ecma_proxy_object_get_own_property_descriptor (object_p, property_name_p, &prop_desc);
3429+
3430+
if (ecma_is_value_true (status))
3431+
{
3432+
ecma_free_property_descriptor (&prop_desc);
3433+
}
3434+
3435+
return status;
3436+
}
3437+
#endif /* JERRY_BUILTIN_PROXY */
3438+
3439+
return ecma_op_ordinary_object_has_own_property (object_p, property_name_p);
3440+
} /* ecma_op_object_has_own_property */
3441+
34133442
#if JERRY_BUILTIN_WEAKREF || JERRY_BUILTIN_CONTAINER
34143443

34153444
/**

jerry-core/ecma/operations/ecma-objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ ecma_property_t ecma_op_object_get_own_property (ecma_object_t *object_p,
5858
ecma_property_ref_t *property_ref_p,
5959
uint32_t options);
6060
ecma_value_t ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
61+
ecma_value_t ecma_op_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
6162
ecma_value_t ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
6263
ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p);
6364
ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *property_name_p);

jerry-core/lit/lit-magic-strings.inc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET_DAY_UL, "getDay")
409409
#if JERRY_BUILTIN_REGEXP
410410
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GLOBAL, "global")
411411
#endif /* JERRY_BUILTIN_REGEXP */
412+
#if JERRY_ESNEXT
413+
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_HAS_OWN_UL, "hasOwn")
414+
#endif /* JERRY_ESNEXT */
412415
#if JERRY_BUILTIN_TYPEDARRAY
413416
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_IS_VIEW_UL, "isView")
414417
#endif /* JERRY_BUILTIN_TYPEDARRAY */

jerry-core/lit/lit-magic-strings.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ LIT_MAGIC_STRING_VALUE = "value"
146146
LIT_MAGIC_STRING_SOURCE_NAME_EVAL = "<eval>"
147147
LIT_MAGIC_STRING_BIGINT_UL = "BigInt"
148148
LIT_MAGIC_STRING_ERRORS_UL = "errors"
149+
LIT_MAGIC_STRING_HAS_OWN_UL = "hasOwn"
149150
LIT_MAGIC_STRING_LOG10E_U = "LOG10E"
150151
LIT_MAGIC_STRING_MODULE_UL = "Module"
151152
LIT_MAGIC_STRING_NUMBER_UL = "Number"

tests/jerry/es.next/object-hasown.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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 obj = { "foo": 5 };
16+
17+
assert(Object.hasOwn(obj, "foo") == true);
18+
assert(Object.hasOwn(obj, "bar") == false);
19+
20+
const handler1 = {};
21+
22+
const handler2 = {
23+
getOwnPropertyDescriptor(target, prop, receiver) {
24+
return { configurable: true, enumerable: true, value: true };
25+
}
26+
};
27+
28+
const handler3 = {
29+
getOwnPropertyDescriptor(target, prop, receiver) { }
30+
};
31+
32+
const proxy1 = new Proxy(obj, handler1);
33+
const proxy2 = new Proxy(obj, handler2);
34+
const proxy3 = new Proxy(obj, handler3);
35+
36+
assert(Object.hasOwn(proxy1, "foo") == true);
37+
assert(Object.hasOwn(proxy1, "bar") == false);
38+
39+
assert(Object.hasOwn(proxy2, "foo") == true);
40+
assert(Object.hasOwn(proxy2, "bar") == true);
41+
42+
assert(Object.hasOwn(proxy3, "foo") == false);
43+
assert(Object.hasOwn(proxy3, "bar") == false);
44+
45+
try {
46+
Object.hasOwn({}, { get toString() { throw "foo" } });
47+
} catch (e) {
48+
assert(e === "foo");
49+
}
50+
51+
try {
52+
Object.hasOwn(undefined);
53+
assert(false);
54+
} catch (e) {
55+
assert(e instanceof TypeError);
56+
}

tests/test262-esnext-excludelist.xml

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4434,69 +4434,6 @@
44344434
<test id="built-ins/TypedArrayConstructors/internals/Set/tonumber-value-detached-buffer.js"><reason></reason></test>
44354435
<!-- END - ESNext: Resizable and growable ArrayBuffer -->
44364436

4437-
<!-- ES2022: Object hasOwn
4438-
https://github.com/tc39/proposal-accessible-object-hasownproperty
4439-
-->
4440-
<test id="built-ins/Object/hasOwn/descriptor.js"><reason></reason></test>
4441-
<test id="built-ins/Object/hasOwn/hasown.js"><reason></reason></test>
4442-
<test id="built-ins/Object/hasOwn/hasown_inherited_exists.js"><reason></reason></test>
4443-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter.js"><reason></reason></test>
4444-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_and_setter.js"><reason></reason></test>
4445-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_and_setter_configurable_enumerable.js"><reason></reason></test>
4446-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_and_setter_configurable_nonenumerable.js"><reason></reason></test>
4447-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_and_setter_nonconfigurable_enumerable.js"><reason></reason></test>
4448-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_and_setter_nonconfigurable_nonenumerable.js"><reason></reason></test>
4449-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_configurable_enumerable.js"><reason></reason></test>
4450-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_configurable_nonenumerable.js"><reason></reason></test>
4451-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_nonconfigurable_enumerable.js"><reason></reason></test>
4452-
<test id="built-ins/Object/hasOwn/hasown_inherited_getter_nonconfigurable_nonenumerable.js"><reason></reason></test>
4453-
<test id="built-ins/Object/hasOwn/hasown_inherited_nonwritable_configurable_enumerable.js"><reason></reason></test>
4454-
<test id="built-ins/Object/hasOwn/hasown_inherited_nonwritable_configurable_nonenumerable.js"><reason></reason></test>
4455-
<test id="built-ins/Object/hasOwn/hasown_inherited_nonwritable_nonconfigurable_enumerable.js"><reason></reason></test>
4456-
<test id="built-ins/Object/hasOwn/hasown_inherited_nonwritable_nonconfigurable_nonenumerable.js"><reason></reason></test>
4457-
<test id="built-ins/Object/hasOwn/hasown_inherited_setter.js"><reason></reason></test>
4458-
<test id="built-ins/Object/hasOwn/hasown_inherited_setter_configurable_enumerable.js"><reason></reason></test>
4459-
<test id="built-ins/Object/hasOwn/hasown_inherited_setter_configurable_nonenumerable.js"><reason></reason></test>
4460-
<test id="built-ins/Object/hasOwn/hasown_inherited_setter_nonconfigurable_enumerable.js"><reason></reason></test>
4461-
<test id="built-ins/Object/hasOwn/hasown_inherited_setter_nonconfigurable_nonenumerable.js"><reason></reason></test>
4462-
<test id="built-ins/Object/hasOwn/hasown_inherited_writable_configurable_enumerable.js"><reason></reason></test>
4463-
<test id="built-ins/Object/hasOwn/hasown_inherited_writable_configurable_nonenumerable.js"><reason></reason></test>
4464-
<test id="built-ins/Object/hasOwn/hasown_inherited_writable_nonconfigurable_enumerable.js"><reason></reason></test>
4465-
<test id="built-ins/Object/hasOwn/hasown_inherited_writable_nonconfigurable_nonenumerable.js"><reason></reason></test>
4466-
<test id="built-ins/Object/hasOwn/hasown_nonexistent.js"><reason></reason></test>
4467-
<test id="built-ins/Object/hasOwn/hasown_own_getter.js"><reason></reason></test>
4468-
<test id="built-ins/Object/hasOwn/hasown_own_getter_and_setter.js"><reason></reason></test>
4469-
<test id="built-ins/Object/hasOwn/hasown_own_getter_and_setter_configurable_enumerable.js"><reason></reason></test>
4470-
<test id="built-ins/Object/hasOwn/hasown_own_getter_and_setter_configurable_nonenumerable.js"><reason></reason></test>
4471-
<test id="built-ins/Object/hasOwn/hasown_own_getter_and_setter_nonconfigurable_enumerable.js"><reason></reason></test>
4472-
<test id="built-ins/Object/hasOwn/hasown_own_getter_and_setter_nonconfigurable_nonenumerable.js"><reason></reason></test>
4473-
<test id="built-ins/Object/hasOwn/hasown_own_getter_configurable_enumerable.js"><reason></reason></test>
4474-
<test id="built-ins/Object/hasOwn/hasown_own_getter_configurable_nonenumerable.js"><reason></reason></test>
4475-
<test id="built-ins/Object/hasOwn/hasown_own_getter_nonconfigurable_enumerable.js"><reason></reason></test>
4476-
<test id="built-ins/Object/hasOwn/hasown_own_getter_nonconfigurable_nonenumerable.js"><reason></reason></test>
4477-
<test id="built-ins/Object/hasOwn/hasown_own_nonwritable_configurable_enumerable.js"><reason></reason></test>
4478-
<test id="built-ins/Object/hasOwn/hasown_own_nonwritable_nonconfigurable_enumerable.js"><reason></reason></test>
4479-
<test id="built-ins/Object/hasOwn/hasown_own_nonwriteable_configurable_nonenumerable.js"><reason></reason></test>
4480-
<test id="built-ins/Object/hasOwn/hasown_own_nonwriteable_nonconfigurable_nonenumerable.js"><reason></reason></test>
4481-
<test id="built-ins/Object/hasOwn/hasown_own_property_exists.js"><reason></reason></test>
4482-
<test id="built-ins/Object/hasOwn/hasown_own_setter.js"><reason></reason></test>
4483-
<test id="built-ins/Object/hasOwn/hasown_own_setter_configurable_enumerable.js"><reason></reason></test>
4484-
<test id="built-ins/Object/hasOwn/hasown_own_setter_configurable_nonenumerable.js"><reason></reason></test>
4485-
<test id="built-ins/Object/hasOwn/hasown_own_setter_nonconfigurable_enumerable.js"><reason></reason></test>
4486-
<test id="built-ins/Object/hasOwn/hasown_own_setter_nonconfigurable_nonenumerable.js"><reason></reason></test>
4487-
<test id="built-ins/Object/hasOwn/hasown_own_writable_configurable_enumerable.js"><reason></reason></test>
4488-
<test id="built-ins/Object/hasOwn/hasown_own_writable_configurable_nonenumerable.js"><reason></reason></test>
4489-
<test id="built-ins/Object/hasOwn/hasown_own_writable_nonconfigurable_enumerable.js"><reason></reason></test>
4490-
<test id="built-ins/Object/hasOwn/hasown_own_writable_nonconfigurable_nonenumerable.js"><reason></reason></test>
4491-
<test id="built-ins/Object/hasOwn/length.js"><reason></reason></test>
4492-
<test id="built-ins/Object/hasOwn/name.js"><reason></reason></test>
4493-
<test id="built-ins/Object/hasOwn/prototype.js"><reason></reason></test>
4494-
<test id="built-ins/Object/hasOwn/symbol_own_property.js"><reason></reason></test>
4495-
<test id="built-ins/Object/hasOwn/symbol_property_toPrimitive.js"><reason></reason></test>
4496-
<test id="built-ins/Object/hasOwn/symbol_property_toString.js"><reason></reason></test>
4497-
<test id="built-ins/Object/hasOwn/symbol_property_valueOf.js"><reason></reason></test>
4498-
<!-- END - ES2022: Object hasOwn -->
4499-
45004437
<!-- ESNext: RegExp hasIndicies
45014438
https://tc39.es/proposal-regexp-match-indices/#sec-get-regexp.prototype.hasIndices
45024439
-->

0 commit comments

Comments
 (0)