Skip to content

Commit ccec24a

Browse files
committed
lib: support returning Safe collections from C++
1 parent fef2128 commit ccec24a

File tree

5 files changed

+50
-0
lines changed

5 files changed

+50
-0
lines changed

src/env.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,28 @@ void Environment::CreateProperties() {
273273
CHECK(primordials->IsObject());
274274
set_primordials(primordials.As<Object>());
275275

276+
Local<String> prototype_string = FIXED_ONE_BYTE_STRING(isolate, "prototype");
277+
278+
#define V(EnvPropertyName, PrimordialsPropertyName) \
279+
{ \
280+
Local<Value> ctor = \
281+
primordials \
282+
->Get(ctx, \
283+
FIXED_ONE_BYTE_STRING(isolate, PrimordialsPropertyName)) \
284+
.ToLocalChecked(); \
285+
CHECK(ctor->IsObject()); \
286+
Local<Value> prototype = \
287+
ctor.As<Object>()->Get(ctx, prototype_string).ToLocalChecked(); \
288+
CHECK(prototype->IsObject()); \
289+
set_##EnvPropertyName(prototype.As<Object>()); \
290+
}
291+
292+
V(primordials_safe_map_prototype_object, "SafeMap");
293+
V(primordials_safe_set_prototype_object, "SafeSet");
294+
V(primordials_safe_weak_map_prototype_object, "SafeWeakMap");
295+
V(primordials_safe_weak_set_prototype_object, "SafeWeakSet");
296+
#undef V
297+
276298
Local<Object> process_object =
277299
node::CreateProcessObject(this).FromMaybe(Local<Object>());
278300
set_process_object(process_object);

src/env.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,10 @@ constexpr size_t kFsStatsBufferLength =
550550
V(prepare_stack_trace_callback, v8::Function) \
551551
V(process_object, v8::Object) \
552552
V(primordials, v8::Object) \
553+
V(primordials_safe_map_prototype_object, v8::Object) \
554+
V(primordials_safe_set_prototype_object, v8::Object) \
555+
V(primordials_safe_weak_map_prototype_object, v8::Object) \
556+
V(primordials_safe_weak_set_prototype_object, v8::Object) \
553557
V(promise_hook_handler, v8::Function) \
554558
V(promise_reject_callback, v8::Function) \
555559
V(script_data_constructor_function, v8::Function) \

src/node_options.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,12 @@ void GetOptions(const FunctionCallbackInfo<Value>& args) {
917917
});
918918

919919
Local<Map> options = Map::New(isolate);
920+
if (options
921+
->SetPrototype(context, env->primordials_safe_map_prototype_object())
922+
.IsNothing()) {
923+
return;
924+
}
925+
920926
for (const auto& item : _ppop_instance.options_) {
921927
Local<Value> value;
922928
const auto& option_info = item.second;

src/uv.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ void GetErrMap(const FunctionCallbackInfo<Value>& args) {
8181
Isolate* isolate = env->isolate();
8282
Local<Context> context = env->context();
8383

84+
// This can't return a SafeMap, because the uv binding can be referenced
85+
// by user code by using `process.binding('uv').getErrorMap()`:
8486
Local<Map> err_map = Map::New(isolate);
8587

8688
size_t errors_len = arraysize(per_process::uv_errors_map);

test/parallel/test-options-binding.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Flags: --expose-internals
2+
'use strict';
3+
4+
require('../common');
5+
const { internalBinding, primordials } = require('internal/test/binding');
6+
const {
7+
SafeMap,
8+
} = primordials;
9+
10+
const options = internalBinding('options');
11+
const assert = require('assert');
12+
13+
assert(
14+
options.getOptions() instanceof SafeMap,
15+
"internalBinding('options').getOptions() returns SafeMap",
16+
);

0 commit comments

Comments
 (0)