From b79ce93010d0cc80a9345f646e562326de4588e5 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 23 Jul 2018 14:11:41 -0400 Subject: [PATCH] Allow deno_buf with null alloc_ptr to be memcpy'd This is a temporary hack to allow for easier restructuring of the serialization code as we move Flatbuffer stuff from C++ to Rust. --- js/mock_runtime.js | 11 +++++++++++ src/binding.cc | 21 +++++++++++++++------ src/mock_runtime_test.cc | 23 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/js/mock_runtime.js b/js/mock_runtime.js index b4f353cdc7536..9fe59ae06c005 100644 --- a/js/mock_runtime.js +++ b/js/mock_runtime.js @@ -134,3 +134,14 @@ global.ErrorHandling = () => { }; eval("\n\n notdefined()\n//# sourceURL=helloworld.js"); }; + +global.SendNullAllocPtr = () => { + deno.recv(msg => { + assert(msg instanceof Uint8Array); + assert(msg.byteLength === 4); + assert(msg[0] === "a".charCodeAt(0)); + assert(msg[1] === "b".charCodeAt(0)); + assert(msg[2] === "c".charCodeAt(0)); + assert(msg[3] === "d".charCodeAt(0)); + }); +}; diff --git a/src/binding.cc b/src/binding.cc index 60325df1ec997..7b5da2d7fc1fb 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -120,12 +120,21 @@ void Print(const v8::FunctionCallbackInfo& args) { } static v8::Local ImportBuf(v8::Isolate* isolate, deno_buf buf) { - auto ab = v8::ArrayBuffer::New( - isolate, reinterpret_cast(buf.alloc_ptr), buf.alloc_len, - v8::ArrayBufferCreationMode::kInternalized); - auto view = - v8::Uint8Array::New(ab, buf.data_ptr - buf.alloc_ptr, buf.data_len); - return view; + if (buf.alloc_ptr == nullptr) { + // If alloc_ptr isn't set, we memcpy. + // This is currently used for flatbuffers created in Rust. + auto ab = v8::ArrayBuffer::New(isolate, buf.data_len); + memcpy(ab->GetContents().Data(), buf.data_ptr, buf.data_len); + auto view = v8::Uint8Array::New(ab, 0, buf.data_len); + return view; + } else { + auto ab = v8::ArrayBuffer::New( + isolate, reinterpret_cast(buf.alloc_ptr), buf.alloc_len, + v8::ArrayBufferCreationMode::kInternalized); + auto view = + v8::Uint8Array::New(ab, buf.data_ptr - buf.alloc_ptr, buf.data_len); + return view; + } } static deno_buf ExportBuf(v8::Isolate* isolate, diff --git a/src/mock_runtime_test.cc b/src/mock_runtime_test.cc index a2c4b3699c68e..fae0b32a58701 100644 --- a/src/mock_runtime_test.cc +++ b/src/mock_runtime_test.cc @@ -34,6 +34,17 @@ deno_buf strbuf(const char* str) { return buf; } +// Same as strbuf but with null alloc_ptr. +deno_buf StrBufNullAllocPtr(const char* str) { + auto len = strlen(str); + deno_buf buf; + buf.alloc_ptr = nullptr; + buf.alloc_len = 0; + buf.data_ptr = reinterpret_cast(strdup(str)); + buf.data_len = len; + return buf; +} + TEST(MockRuntimeTest, SendSuccess) { Deno* d = deno_new(nullptr, nullptr); EXPECT_TRUE(deno_execute(d, "a.js", "SendSuccess()")); @@ -176,3 +187,15 @@ TEST(MockRuntimeTest, ErrorHandling) { EXPECT_EQ(count, 1); deno_delete(d); } + +TEST(MockRuntimeTest, SendNullAllocPtr) { + static int count = 0; + Deno* d = deno_new(nullptr, [](auto _, auto buf) { count++; }); + EXPECT_TRUE(deno_execute(d, "a.js", "SendNullAllocPtr()")); + deno_buf buf = StrBufNullAllocPtr("abcd"); + EXPECT_EQ(buf.alloc_ptr, nullptr); + EXPECT_EQ(buf.data_len, 4u); + EXPECT_TRUE(deno_send(d, buf)); + EXPECT_EQ(count, 0); + deno_delete(d); +}