Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5faaa60

Browse filesBrowse files
codebytereMylesBorins
authored andcommitted
n-api: support for object freeze/seal
PR-URL: #35359 Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
1 parent 6952c45 commit 5faaa60
Copy full SHA for 5faaa60

File tree

Expand file treeCollapse file tree

5 files changed

+153
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+153
-0
lines changed
Open diff view settings
Collapse file

‎doc/api/n-api.md‎

Copy file name to clipboardExpand all lines: doc/api/n-api.md
+47Lines changed: 47 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -4092,6 +4092,53 @@ this API will set the properties on the object one at a time, as defined by
40924092
`DefineOwnProperty()` (described in [Section 9.1.6][] of the ECMA-262
40934093
specification).
40944094

4095+
#### napi_object_freeze
4096+
<!-- YAML
4097+
added: REPLACEME
4098+
-->
4099+
4100+
> Stability: 1 - Experimental
4101+
4102+
```c
4103+
napi_status napi_object_freeze(napi_env env,
4104+
napi_value object);
4105+
```
4106+
4107+
* `[in] env`: The environment that the N-API call is invoked under.
4108+
* `[in] object`: The object to freeze.
4109+
4110+
Returns `napi_ok` if the API succeeded.
4111+
4112+
This method freezes a given object. This prevents new properties from
4113+
being added to it, existing properties from being removed, prevents
4114+
changing the enumerability, configurability, or writability of existing
4115+
properties, and prevents the values of existing properties from being changed.
4116+
It also prevents the object's prototype from being changed. This is described
4117+
in [Section 19.1.2.6](https://tc39.es/ecma262/#sec-object.freeze) of the
4118+
ECMA-262 specification.
4119+
4120+
#### napi_object_seal
4121+
<!-- YAML
4122+
added: REPLACEME
4123+
-->
4124+
4125+
> Stability: 1 - Experimental
4126+
4127+
```c
4128+
napi_status napi_object_seal(napi_env env,
4129+
napi_value object);
4130+
```
4131+
4132+
* `[in] env`: The environment that the N-API call is invoked under.
4133+
* `[in] object`: The object to seal.
4134+
4135+
Returns `napi_ok` if the API succeeded.
4136+
4137+
This method seals a given object. This prevents new properties from being
4138+
added to it, as well as marking all existing properties as non-configurable.
4139+
This is described in [Section 19.1.2.20](https://tc39.es/ecma262/#sec-object.seal)
4140+
of the ECMA-262 specification.
4141+
40954142
## Working with JavaScript functions
40964143

40974144
N-API provides a set of APIs that allow JavaScript code to
Collapse file

‎src/js_native_api.h‎

Copy file name to clipboardExpand all lines: src/js_native_api.h
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,10 @@ napi_check_object_type_tag(napi_env env,
550550
napi_value value,
551551
const napi_type_tag* type_tag,
552552
bool* result);
553+
NAPI_EXTERN napi_status napi_object_freeze(napi_env env,
554+
napi_value object);
555+
NAPI_EXTERN napi_status napi_object_seal(napi_env env,
556+
napi_value object);
553557
#endif // NAPI_EXPERIMENTAL
554558

555559
EXTERN_C_END
Collapse file

‎src/js_native_api_v8.cc‎

Copy file name to clipboardExpand all lines: src/js_native_api_v8.cc
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,42 @@ napi_status napi_define_properties(napi_env env,
13941394
return GET_RETURN_STATUS(env);
13951395
}
13961396

1397+
napi_status napi_object_freeze(napi_env env,
1398+
napi_value object) {
1399+
NAPI_PREAMBLE(env);
1400+
1401+
v8::Local<v8::Context> context = env->context();
1402+
v8::Local<v8::Object> obj;
1403+
1404+
CHECK_TO_OBJECT(env, context, obj, object);
1405+
1406+
v8::Maybe<bool> set_frozen =
1407+
obj->SetIntegrityLevel(context, v8::IntegrityLevel::kFrozen);
1408+
1409+
RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env,
1410+
set_frozen.FromMaybe(false), napi_generic_failure);
1411+
1412+
return GET_RETURN_STATUS(env);
1413+
}
1414+
1415+
napi_status napi_object_seal(napi_env env,
1416+
napi_value object) {
1417+
NAPI_PREAMBLE(env);
1418+
1419+
v8::Local<v8::Context> context = env->context();
1420+
v8::Local<v8::Object> obj;
1421+
1422+
CHECK_TO_OBJECT(env, context, obj, object);
1423+
1424+
v8::Maybe<bool> set_sealed =
1425+
obj->SetIntegrityLevel(context, v8::IntegrityLevel::kSealed);
1426+
1427+
RETURN_STATUS_IF_FALSE_WITH_PREAMBLE(env,
1428+
set_sealed.FromMaybe(false), napi_generic_failure);
1429+
1430+
return GET_RETURN_STATUS(env);
1431+
}
1432+
13971433
napi_status napi_is_array(napi_env env, napi_value value, bool* result) {
13981434
CHECK_ENV(env);
13991435
CHECK_ARG(env, value);
Collapse file

‎test/js-native-api/test_object/test.js‎

Copy file name to clipboardExpand all lines: test/js-native-api/test_object/test.js
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,43 @@ assert.deepStrictEqual(test_object.TestGetProperty(), {
275275
keyIsNull: 'Invalid argument',
276276
resultIsNull: 'Invalid argument'
277277
});
278+
279+
{
280+
const obj = { x: 'a', y: 'b', z: 'c' };
281+
282+
test_object.TestSeal(obj);
283+
284+
assert.strictEqual(Object.isSealed(obj), true);
285+
286+
assert.throws(() => {
287+
obj.w = 'd';
288+
}, /Cannot add property w, object is not extensible/);
289+
290+
assert.throws(() => {
291+
delete obj.x;
292+
}, /Cannot delete property 'x' of #<Object>/);
293+
294+
// Sealed objects allow updating existing properties,
295+
// so this should not throw.
296+
obj.x = 'd';
297+
}
298+
299+
{
300+
const obj = { x: 10, y: 10, z: 10 };
301+
302+
test_object.TestFreeze(obj);
303+
304+
assert.strictEqual(Object.isFrozen(obj), true);
305+
306+
assert.throws(() => {
307+
obj.x = 10;
308+
}, /Cannot assign to read only property 'x' of object '#<Object>/);
309+
310+
assert.throws(() => {
311+
obj.w = 15;
312+
}, /Cannot add property w, object is not extensible/);
313+
314+
assert.throws(() => {
315+
delete obj.x;
316+
}, /Cannot delete property 'x' of #<Object>/);
317+
}
Collapse file

‎test/js-native-api/test_object/test_object.c‎

Copy file name to clipboardExpand all lines: test/js-native-api/test_object/test_object.c
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,30 @@ static napi_value TestGetProperty(napi_env env,
472472
return object;
473473
}
474474

475+
static napi_value TestFreeze(napi_env env,
476+
napi_callback_info info) {
477+
size_t argc = 1;
478+
napi_value args[1];
479+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
480+
481+
napi_value object = args[0];
482+
NAPI_CALL(env, napi_object_freeze(env, object));
483+
484+
return object;
485+
}
486+
487+
static napi_value TestSeal(napi_env env,
488+
napi_callback_info info) {
489+
size_t argc = 1;
490+
napi_value args[1];
491+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
492+
493+
napi_value object = args[0];
494+
NAPI_CALL(env, napi_object_seal(env, object));
495+
496+
return object;
497+
}
498+
475499
// We create two type tags. They are basically 128-bit UUIDs.
476500
static const napi_type_tag type_tags[2] = {
477501
{ 0xdaf987b3cc62481a, 0xb745b0497f299531 },
@@ -532,6 +556,8 @@ napi_value Init(napi_env env, napi_value exports) {
532556
DECLARE_NAPI_PROPERTY("TypeTaggedInstance", TypeTaggedInstance),
533557
DECLARE_NAPI_PROPERTY("CheckTypeTag", CheckTypeTag),
534558
DECLARE_NAPI_PROPERTY("TestGetProperty", TestGetProperty),
559+
DECLARE_NAPI_PROPERTY("TestFreeze", TestFreeze),
560+
DECLARE_NAPI_PROPERTY("TestSeal", TestSeal),
535561
};
536562

537563
init_test_null(env, exports);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.