Skip to content

Commit e538d3c

Browse files
committed
src: add ArrayBuffer::Detach() and ::IsDetached()
Refs: nodejs/node#29768 Refs: nodejs/node#30613 PR-URL: nodejs/node-addon-api#659 Refs: nodejs/node#29768 Refs: nodejs/node#30613 Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Gabriel Schulhof <[email protected]>
1 parent 5a36cde commit e538d3c

File tree

5 files changed

+71
-7
lines changed

5 files changed

+71
-7
lines changed

doc/array_buffer.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,20 @@ void* Napi::ArrayBuffer::Data() const;
130130

131131
Returns a pointer the wrapped data.
132132

133+
### Detach
134+
135+
```cpp
136+
void Napi::ArrayBuffer::Detach();
137+
```
138+
139+
Invokes the `ArrayBuffer` detach operation on a detachable `ArrayBuffer`.
140+
141+
### IsDetached
142+
143+
```cpp
144+
bool Napi::ArrayBuffer::IsDetached() const;
145+
```
146+
147+
Returns `true` if this `ArrayBuffer` has been detached.
148+
133149
[`Napi::Object`]: ./object.md

napi-inl.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,20 @@ inline size_t ArrayBuffer::ByteLength() {
15301530
return length;
15311531
}
15321532

1533+
#if NAPI_VERSION >= 7
1534+
inline bool ArrayBuffer::IsDetached() const {
1535+
bool detached;
1536+
napi_status status = napi_is_detached_arraybuffer(_env, _value, &detached);
1537+
NAPI_THROW_IF_FAILED(_env, status, false);
1538+
return detached;
1539+
}
1540+
1541+
inline void ArrayBuffer::Detach() {
1542+
napi_status status = napi_detach_arraybuffer(_env, _value);
1543+
NAPI_THROW_IF_FAILED_VOID(_env, status);
1544+
}
1545+
#endif // NAPI_VERSION >= 7
1546+
15331547
////////////////////////////////////////////////////////////////////////////////
15341548
// DataView class
15351549
////////////////////////////////////////////////////////////////////////////////

napi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,11 @@ namespace Napi {
822822

823823
void* Data(); ///< Gets a pointer to the data buffer.
824824
size_t ByteLength(); ///< Gets the length of the array buffer in bytes.
825+
826+
#if NAPI_VERSION >= 7
827+
bool IsDetached() const;
828+
void Detach();
829+
#endif // NAPI_VERSION >= 7
825830
};
826831

827832
/// A JavaScript typed-array value with unknown array type.

test/arraybuffer.cc

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,43 @@ void CheckDetachUpdatesData(const CallbackInfo& info) {
157157
return;
158158
}
159159

160-
if (!info[1].IsFunction()) {
161-
Error::New(info.Env(), "A function was expected.").ThrowAsJavaScriptException();
162-
return;
163-
}
164-
165160
ArrayBuffer buffer = info[0].As<ArrayBuffer>();
166-
Function detach = info[1].As<Function>();
167161

168162
// This potentially causes the buffer to cache its data pointer and length.
169163
buffer.Data();
170164
buffer.ByteLength();
171165

172-
detach.Call({});
166+
#if NAPI_VERSION >= 7
167+
if (buffer.IsDetached()) {
168+
Error::New(info.Env(), "Buffer should not be detached.").ThrowAsJavaScriptException();
169+
return;
170+
}
171+
#endif
172+
173+
if (info.Length() == 2) {
174+
// Detach externally (in JavaScript).
175+
if (!info[1].IsFunction()) {
176+
Error::New(info.Env(), "A function was expected.").ThrowAsJavaScriptException();
177+
return;
178+
}
179+
180+
Function detach = info[1].As<Function>();
181+
detach.Call({});
182+
} else {
183+
#if NAPI_VERSION >= 7
184+
// Detach directly.
185+
buffer.Detach();
186+
#else
187+
return;
188+
#endif
189+
}
190+
191+
#if NAPI_VERSION >= 7
192+
if (!buffer.IsDetached()) {
193+
Error::New(info.Env(), "Buffer should be detached.").ThrowAsJavaScriptException();
194+
return;
195+
}
196+
#endif
173197

174198
if (buffer.Data() != nullptr) {
175199
Error::New(info.Env(), "Incorrect data pointer.").ThrowAsJavaScriptException();

test/arraybuffer.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ function test(binding) {
5858

5959
'ArrayBuffer updates data pointer and length when detached',
6060
() => {
61+
// Detach the ArrayBuffer in JavaScript.
6162
const mem = new WebAssembly.Memory({ initial: 1 });
6263
binding.arraybuffer.checkDetachUpdatesData(mem.buffer, () => mem.grow(1));
64+
65+
// Let C++ detach the ArrayBuffer.
66+
const extBuffer = binding.arraybuffer.createExternalBuffer();
67+
binding.arraybuffer.checkDetachUpdatesData(extBuffer);
6368
},
6469
]);
6570
}

0 commit comments

Comments
 (0)