summaryrefslogtreecommitdiff
path: root/libdeno/binding.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2019-02-26 17:36:05 -0500
committerGitHub <noreply@github.com>2019-02-26 17:36:05 -0500
commitb8a537d020f5e4495572daa4d8a59f51fa3b20d1 (patch)
tree468164b8dcc8ce0bcd64e75b63e4a3af0da36f15 /libdeno/binding.cc
parent5dfbbbb07a8f484dca27bbe0d7a3bafb0bdb91fd (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.cc61
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);
- }
}
}