Skip to content

Commit f2b1f83

Browse files
committed
node-api: support SharedArrayBuffer in napi_create_dataview
1 parent dec0213 commit f2b1f83

File tree

4 files changed

+60
-19
lines changed

4 files changed

+60
-19
lines changed

src/js_native_api_v8.cc

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,21 +3298,30 @@ napi_status NAPI_CDECL napi_create_dataview(napi_env env,
32983298
CHECK_ARG(env, result);
32993299

33003300
v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(arraybuffer);
3301-
RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg);
33023301

3303-
v8::Local<v8::ArrayBuffer> buffer = value.As<v8::ArrayBuffer>();
3304-
if (byte_length + byte_offset > buffer->ByteLength()) {
3305-
napi_throw_range_error(env,
3306-
"ERR_NAPI_INVALID_DATAVIEW_ARGS",
3307-
"byte_offset + byte_length should be less than or "
3308-
"equal to the size in bytes of the array passed in");
3309-
return napi_set_last_error(env, napi_pending_exception);
3310-
}
3311-
v8::Local<v8::DataView> DataView =
3312-
v8::DataView::New(buffer, byte_offset, byte_length);
3302+
auto create_dataview = [&](auto buffer) -> napi_status {
3303+
if (byte_length + byte_offset > buffer->ByteLength()) {
3304+
napi_throw_range_error(
3305+
env,
3306+
"ERR_NAPI_INVALID_DATAVIEW_ARGS",
3307+
"byte_offset + byte_length should be less than or "
3308+
"equal to the size in bytes of the array passed in");
3309+
return napi_set_last_error(env, napi_pending_exception);
3310+
}
33133311

3314-
*result = v8impl::JsValueFromV8LocalValue(DataView);
3315-
return GET_RETURN_STATUS(env);
3312+
v8::Local<v8::DataView> data_view =
3313+
v8::DataView::New(buffer, byte_offset, byte_length);
3314+
*result = v8impl::JsValueFromV8LocalValue(data_view);
3315+
return GET_RETURN_STATUS(env);
3316+
};
3317+
3318+
if (value->IsArrayBuffer()) {
3319+
return create_dataview(value.As<v8::ArrayBuffer>());
3320+
} else if (value->IsSharedArrayBuffer()) {
3321+
return create_dataview(value.As<v8::SharedArrayBuffer>());
3322+
} else {
3323+
return napi_set_last_error(env, napi_invalid_arg);
3324+
}
33163325
}
33173326

33183327
napi_status NAPI_CDECL napi_is_dataview(napi_env env,

test/js-native-api/test_dataview/binding.gyp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
"target_name": "test_dataview",
55
"sources": [
66
"test_dataview.c"
7-
]
7+
],
8+
9+
# For node_api_is_sharedarraybuffer
10+
'defines': [ 'NAPI_EXPERIMENTAL', 'NODE_API_EXPERIMENTAL_NO_WARNING' ]
811
}
912
]
1013
}

test/js-native-api/test_dataview/test.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const assert = require('assert');
55
// Testing api calls for arrays
66
const test_dataview = require(`./build/${common.buildType}/test_dataview`);
77

8-
// Test for creating dataview
8+
// Test for creating dataview with ArrayBuffer
99
{
1010
const buffer = new ArrayBuffer(128);
1111
const template = Reflect.construct(DataView, [buffer]);
@@ -15,10 +15,30 @@ const test_dataview = require(`./build/${common.buildType}/test_dataview`);
1515
`Expect ${theDataview} to be a DataView`);
1616
}
1717

18-
// Test for creating dataview with invalid range
18+
// Test for creating dataview with SharedArrayBuffer
19+
{
20+
const buffer = new SharedArrayBuffer(128);
21+
const template = Reflect.construct(DataView, [buffer]);
22+
23+
const theDataview = test_dataview.CreateDataViewFromJSDataView(template);
24+
assert.ok(theDataview instanceof DataView,
25+
`Expect ${theDataview} to be a DataView`);
26+
27+
assert.strictEqual(template.buffer, theDataview.buffer);
28+
}
29+
30+
// Test for creating dataview with ArrayBuffer and invalid range
1931
{
2032
const buffer = new ArrayBuffer(128);
2133
assert.throws(() => {
2234
test_dataview.CreateDataView(buffer, 10, 200);
2335
}, RangeError);
2436
}
37+
38+
// Test for creating dataview with SharedArrayBuffer and invalid range
39+
{
40+
const buffer = new SharedArrayBuffer(128);
41+
assert.throws(() => {
42+
test_dataview.CreateDataView(buffer, 10, 200);
43+
}, RangeError);
44+
}

test/js-native-api/test_dataview/test_dataview.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,18 @@ static napi_value CreateDataView(napi_env env, napi_callback_info info) {
2020

2121
bool is_arraybuffer;
2222
NODE_API_CALL(env, napi_is_arraybuffer(env, arraybuffer, &is_arraybuffer));
23-
NODE_API_ASSERT(env, is_arraybuffer,
24-
"Wrong type of arguments. Expects a ArrayBuffer as the first "
25-
"argument.");
23+
24+
if (!is_arraybuffer) {
25+
bool is_sharedarraybuffer;
26+
NODE_API_CALL(
27+
env,
28+
node_api_is_sharedarraybuffer(env, arraybuffer, &is_sharedarraybuffer));
29+
NODE_API_ASSERT(env,
30+
is_sharedarraybuffer,
31+
"Wrong type of arguments. Expects a SharedArrayBuffer or "
32+
"ArrayBuffer as the first "
33+
"argument.");
34+
}
2635

2736
napi_valuetype valuetype1;
2837
NODE_API_CALL(env, napi_typeof(env, args[1], &valuetype1));

0 commit comments

Comments
 (0)