diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2019-02-26 17:36:05 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-26 17:36:05 -0500 |
commit | b8a537d020f5e4495572daa4d8a59f51fa3b20d1 (patch) | |
tree | 468164b8dcc8ce0bcd64e75b63e4a3af0da36f15 /libdeno/binding.cc | |
parent | 5dfbbbb07a8f484dca27bbe0d7a3bafb0bdb91fd (diff) |
deno_core (#1827)
A new low-level crate with focus on speed.
This doesn't yet hook into the existing code base.
Diffstat (limited to 'libdeno/binding.cc')
-rw-r--r-- | libdeno/binding.cc | 61 |
1 files changed, 28 insertions, 33 deletions
diff --git a/libdeno/binding.cc b/libdeno/binding.cc index f640fe83c..d4849db7b 100644 --- a/libdeno/binding.cc +++ b/libdeno/binding.cc @@ -44,20 +44,6 @@ v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index, return {payload, size}; } -void AddDataRef(DenoIsolate* d, int32_t req_id, v8::Local<v8::Value> data_v) { - d->async_data_map_.emplace(std::piecewise_construct, std::make_tuple(req_id), - std::make_tuple(d->isolate_, data_v)); -} - -void DeleteDataRef(DenoIsolate* d, int32_t req_id) { - // Delete persistent reference to data ArrayBuffer. - auto it = d->async_data_map_.find(req_id); - if (it != d->async_data_map_.end()) { - it->second.Reset(); - d->async_data_map_.erase(it); - } -} - // Extracts a C string from a v8::V8 Utf8Value. const char* ToCString(const v8::String::Utf8Value& value) { return *value ? *value : "<string conversion failed>"; @@ -131,6 +117,13 @@ void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args) { } v8::Local<v8::Uint8Array> ImportBuf(DenoIsolate* d, deno_buf buf) { + // Do not use ImportBuf with zero_copy buffers. + DCHECK_EQ(buf.zero_copy_id, 0); + + if (buf.data_ptr == nullptr) { + return v8::Local<v8::Uint8Array>(); + } + if (buf.alloc_ptr == nullptr) { // If alloc_ptr isn't set, we memcpy. // This is currently used for flatbuffers created in Rust. @@ -209,42 +202,44 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) { DenoIsolate* d = DenoIsolate::FromIsolate(isolate); DCHECK_EQ(d->isolate_, isolate); - v8::Locker locker(d->isolate_); + deno_buf control = {nullptr, 0u, nullptr, 0u, 0u}; + deno_buf zero_copy = {nullptr, 0u, nullptr, 0u, 0u}; + v8::HandleScope handle_scope(isolate); - CHECK_NULL(d->current_args_); // libdeno.send re-entry forbidden. - int32_t req_id = d->next_req_id_++; + if (args.Length() > 0) { + v8::Local<v8::Value> control_v = args[0]; + if (control_v->IsArrayBufferView()) { + control = + GetContents(isolate, v8::Local<v8::ArrayBufferView>::Cast(control_v)); + } + } - v8::Local<v8::Value> control_v = args[0]; - CHECK(control_v->IsArrayBufferView()); - deno_buf control = - GetContents(isolate, v8::Local<v8::ArrayBufferView>::Cast(control_v)); - deno_buf data = {nullptr, 0u, nullptr, 0u}; - v8::Local<v8::Value> data_v; + v8::Local<v8::Value> zero_copy_v; if (args.Length() == 2) { if (args[1]->IsArrayBufferView()) { - data_v = args[1]; - data = GetContents(isolate, v8::Local<v8::ArrayBufferView>::Cast(data_v)); + zero_copy_v = args[1]; + zero_copy = GetContents( + isolate, v8::Local<v8::ArrayBufferView>::Cast(zero_copy_v)); + size_t zero_copy_id = d->next_zero_copy_id_++; + DCHECK_GT(zero_copy_id, 0); + zero_copy.zero_copy_id = zero_copy_id; + // If the zero_copy ArrayBuffer was given, we must maintain a strong + // reference to it until deno_zero_copy_release is called. + d->AddZeroCopyRef(zero_copy_id, zero_copy_v); } - } else { - CHECK_EQ(args.Length(), 1); } DCHECK_NULL(d->current_args_); d->current_args_ = &args; - d->recv_cb_(d->user_data_, req_id, control, data); + d->recv_cb_(d->user_data_, control, zero_copy); if (d->current_args_ == nullptr) { // This indicates that deno_repond() was called already. } else { // Asynchronous. d->current_args_ = nullptr; - // If the data ArrayBuffer was given, we must maintain a strong reference - // to it until deno_respond is called. - if (!data_v.IsEmpty()) { - AddDataRef(d, req_id, data_v); - } } } |