From bbe2004f5d2b434fe5942fc3c8954a297b317fd0 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Fri, 8 Feb 2019 20:32:17 -0800 Subject: [PATCH] Shared buffer fixes (#1644) * makes `libdeno.shared` a `SharedArrayBuffer` instead of a regular `ArrayBuffer`. * fixes `libdeno.shared` becoming undefined after accessing it once. --- libdeno/binding.cc | 9 +++++---- libdeno/internal.h | 3 ++- libdeno/libdeno_test.cc | 13 +++++++++++++ libdeno/libdeno_test.js | 3 ++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libdeno/binding.cc b/libdeno/binding.cc index 961fd17978..78e4cad296 100644 --- a/libdeno/binding.cc +++ b/libdeno/binding.cc @@ -316,14 +316,15 @@ void Shared(v8::Local property, if (d->shared_.data_ptr == nullptr) { return; } - v8::Local ab; + v8::Local ab; if (d->shared_ab_.IsEmpty()) { // Lazily initialize the persistent external ArrayBuffer. - ab = v8::ArrayBuffer::New(isolate, d->shared_.data_ptr, d->shared_.data_len, - v8::ArrayBufferCreationMode::kExternalized); + ab = v8::SharedArrayBuffer::New(isolate, d->shared_.data_ptr, + d->shared_.data_len, + v8::ArrayBufferCreationMode::kExternalized); d->shared_ab_.Reset(isolate, ab); } - info.GetReturnValue().Set(ab); + info.GetReturnValue().Set(d->shared_ab_); } void DenoIsolate::ClearModules() { diff --git a/libdeno/internal.h b/libdeno/internal.h index 14a9cd43f5..0cd50162c3 100644 --- a/libdeno/internal.h +++ b/libdeno/internal.h @@ -46,6 +46,7 @@ class DenoIsolate { } ~DenoIsolate() { + shared_ab_.Reset(); if (snapshot_creator_) { delete snapshot_creator_; } else { @@ -98,7 +99,7 @@ class DenoIsolate { v8::Persistent recv_; v8::StartupData snapshot_; v8::Persistent global_import_buf_; - v8::Persistent shared_ab_; + v8::Persistent shared_ab_; }; class UserDataScope { diff --git a/libdeno/libdeno_test.cc b/libdeno/libdeno_test.cc index b14b4758bf..0936c53b42 100644 --- a/libdeno/libdeno_test.cc +++ b/libdeno/libdeno_test.cc @@ -289,3 +289,16 @@ TEST(LibDenoTest, Utf8Bug) { EXPECT_EQ(nullptr, deno_last_exception(d)); deno_delete(d); } + +TEST(LibDenoTest, SharedAtomics) { + int32_t s[] = {0, 1, 2}; + deno_buf shared = {nullptr, 0, reinterpret_cast(s), sizeof s}; + Deno* d = deno_new(deno_config{0, empty, shared, nullptr}); + deno_execute(d, nullptr, "a.js", + "Atomics.add(new Int32Array(libdeno.shared), 0, 1)"); + EXPECT_EQ(nullptr, deno_last_exception(d)); + EXPECT_EQ(s[0], 1); + EXPECT_EQ(s[1], 1); + EXPECT_EQ(s[2], 2); + deno_delete(d); +} diff --git a/libdeno/libdeno_test.js b/libdeno/libdeno_test.js index 5e1430d9e2..50f5c03d4c 100644 --- a/libdeno/libdeno_test.js +++ b/libdeno/libdeno_test.js @@ -136,7 +136,8 @@ global.CheckPromiseErrors = () => { global.Shared = () => { const ab = libdeno.shared; - assert(ab instanceof ArrayBuffer); + assert(ab instanceof SharedArrayBuffer); + assert(libdeno.shared != undefined); assert(ab.byteLength === 3); const ui8 = new Uint8Array(ab); assert(ui8[0] === 0);