summaryrefslogtreecommitdiff
path: root/libdeno/binding.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libdeno/binding.cc')
-rw-r--r--libdeno/binding.cc293
1 files changed, 89 insertions, 204 deletions
diff --git a/libdeno/binding.cc b/libdeno/binding.cc
index 3a3f171e6..9fca3814c 100644
--- a/libdeno/binding.cc
+++ b/libdeno/binding.cc
@@ -5,7 +5,6 @@
#include <iostream>
#include <string>
-#include "third_party/v8/include/libplatform/libplatform.h"
#include "third_party/v8/include/v8.h"
#include "third_party/v8/src/base/logging.h"
@@ -16,21 +15,36 @@
namespace deno {
-Deno* FromIsolate(v8::Isolate* isolate) {
- return static_cast<Deno*>(isolate->GetData(0));
+std::vector<InternalFieldData*> deserialized_data;
+
+void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
+ v8::StartupData payload, void* data) {
+ DCHECK_EQ(data, nullptr);
+ if (payload.raw_size == 0) {
+ holder->SetAlignedPointerInInternalField(index, nullptr);
+ return;
+ }
+ InternalFieldData* embedder_field = new InternalFieldData{0};
+ memcpy(embedder_field, payload.data, payload.raw_size);
+ holder->SetAlignedPointerInInternalField(index, embedder_field);
+ deserialized_data.push_back(embedder_field);
}
-void AddDataRef(Deno* 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));
+DenoIsolate* FromIsolate(v8::Isolate* isolate) {
+ return static_cast<DenoIsolate*>(isolate->GetData(0));
}
-void DeleteDataRef(Deno* d, int32_t req_id) {
+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()) {
+ 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);
+ d->async_data_map_.erase(it);
}
}
@@ -49,7 +63,7 @@ void HandleExceptionStr(v8::Local<v8::Context> context,
v8::Local<v8::Value> exception,
std::string* exception_str) {
auto* isolate = context->GetIsolate();
- Deno* d = FromIsolate(isolate);
+ DenoIsolate* d = FromIsolate(isolate);
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
@@ -61,10 +75,10 @@ void HandleExceptionStr(v8::Local<v8::Context> context,
auto column =
v8::Integer::New(isolate, message->GetStartColumn(context).FromJust());
- auto global_error_handler = d->global_error_handler.Get(isolate);
+ auto global_error_handler_ = d->global_error_handler_.Get(isolate);
- if (!global_error_handler.IsEmpty()) {
- // global_error_handler is set so we try to handle the exception in
+ if (!global_error_handler_.IsEmpty()) {
+ // global_error_handler_ is set so we try to handle the exception in
// javascript.
v8::Local<v8::Value> args[5];
args[0] = exception->ToString(context).ToLocalChecked();
@@ -72,7 +86,7 @@ void HandleExceptionStr(v8::Local<v8::Context> context,
args[2] = line;
args[3] = column;
args[4] = exception;
- global_error_handler->Call(context->Global(), 5, args);
+ global_error_handler_->Call(context->Global(), 5, args);
/* message, source, lineno, colno, error */
return;
@@ -81,7 +95,7 @@ void HandleExceptionStr(v8::Local<v8::Context> context,
char buf[12 * 1024];
if (!stack_trace.IsEmpty()) {
// No javascript error handler, but we do have a stack trace. Format it
- // into a string and add to last_exception.
+ // into a string and add to last_exception_.
std::string msg;
v8::String::Utf8Value exceptionStr(isolate, exception);
msg += ToCString(exceptionStr);
@@ -98,7 +112,7 @@ void HandleExceptionStr(v8::Local<v8::Context> context,
*exception_str += msg;
} else {
// No javascript error handler, no stack trace. Format the little info we
- // have into a string and add to last_exception.
+ // have into a string and add to last_exception_.
v8::String::Utf8Value exceptionStr(isolate, exception);
v8::String::Utf8Value script_name(isolate,
message->GetScriptResourceName());
@@ -113,11 +127,11 @@ void HandleExceptionStr(v8::Local<v8::Context> context,
void HandleException(v8::Local<v8::Context> context,
v8::Local<v8::Value> exception) {
v8::Isolate* isolate = context->GetIsolate();
- Deno* d = FromIsolate(isolate);
+ DenoIsolate* d = FromIsolate(isolate);
std::string exception_str;
HandleExceptionStr(context, exception, &exception_str);
if (d != nullptr) {
- d->last_exception = exception_str;
+ d->last_exception_ = exception_str;
} else {
std::cerr << "Pre-Deno Exception " << exception_str << std::endl;
exit(1);
@@ -139,16 +153,16 @@ const char* PromiseRejectStr(enum v8::PromiseRejectEvent e) {
void PromiseRejectCallback(v8::PromiseRejectMessage promise_reject_message) {
auto* isolate = v8::Isolate::GetCurrent();
- Deno* d = static_cast<Deno*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate, isolate);
- v8::HandleScope handle_scope(d->isolate);
+ DenoIsolate* d = static_cast<DenoIsolate*>(isolate->GetData(0));
+ DCHECK_EQ(d->isolate_, isolate);
+ v8::HandleScope handle_scope(d->isolate_);
auto exception = promise_reject_message.GetValue();
- auto context = d->context.Get(d->isolate);
+ auto context = d->context_.Get(d->isolate_);
auto promise = promise_reject_message.GetPromise();
auto event = promise_reject_message.GetEvent();
v8::Context::Scope context_scope(context);
- auto promise_reject_handler = d->promise_reject_handler.Get(isolate);
+ auto promise_reject_handler = d->promise_reject_handler_.Get(isolate);
if (!promise_reject_handler.IsEmpty()) {
v8::Local<v8::Value> args[3];
@@ -156,22 +170,22 @@ void PromiseRejectCallback(v8::PromiseRejectMessage promise_reject_message) {
args[2] = promise;
/* error, event, promise */
if (event == v8::PromiseRejectEvent::kPromiseRejectWithNoHandler) {
- d->pending_promise_events++;
+ d->pending_promise_events_++;
// exception only valid for kPromiseRejectWithNoHandler
args[0] = exception;
} else if (event ==
v8::PromiseRejectEvent::kPromiseHandlerAddedAfterReject) {
- d->pending_promise_events--; // unhandled event cancelled
- if (d->pending_promise_events < 0) {
- d->pending_promise_events = 0;
+ d->pending_promise_events_--; // unhandled event cancelled
+ if (d->pending_promise_events_ < 0) {
+ d->pending_promise_events_ = 0;
}
// Placeholder, not actually used
args[0] = v8_str("Promise handler added");
} else if (event == v8::PromiseRejectEvent::kPromiseResolveAfterResolved) {
- d->pending_promise_events++;
+ d->pending_promise_events_++;
args[0] = v8_str("Promise resolved after resolved");
} else if (event == v8::PromiseRejectEvent::kPromiseRejectAfterResolved) {
- d->pending_promise_events++;
+ d->pending_promise_events_++;
args[0] = v8_str("Promise rejected after resolved");
}
promise_reject_handler->Call(context->Global(), 3, args);
@@ -183,8 +197,8 @@ void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK_GE(args.Length(), 1);
CHECK_LE(args.Length(), 2);
auto* isolate = args.GetIsolate();
- Deno* d = static_cast<Deno*>(isolate->GetData(0));
- auto context = d->context.Get(d->isolate);
+ DenoIsolate* d = FromIsolate(isolate);
+ auto context = d->context_.Get(d->isolate_);
v8::HandleScope handle_scope(isolate);
v8::String::Utf8Value str(isolate, args[0]);
bool is_err =
@@ -194,7 +208,7 @@ void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
stream << cstr << std::endl;
}
-static v8::Local<v8::Uint8Array> ImportBuf(Deno* d, deno_buf buf) {
+v8::Local<v8::Uint8Array> ImportBuf(DenoIsolate* d, deno_buf buf) {
if (buf.alloc_ptr == nullptr) {
// If alloc_ptr isn't set, we memcpy.
// This is currently used for flatbuffers created in Rust.
@@ -207,28 +221,28 @@ static v8::Local<v8::Uint8Array> ImportBuf(Deno* d, deno_buf buf) {
void* data;
if (buf.data_len > GLOBAL_IMPORT_BUF_SIZE) {
// Simple case. We allocate a new ArrayBuffer for this.
- ab = v8::ArrayBuffer::New(d->isolate, buf.data_len);
+ ab = v8::ArrayBuffer::New(d->isolate_, buf.data_len);
data = ab->GetContents().Data();
} else {
// Fast case. We reuse the global ArrayBuffer.
- if (d->global_import_buf.IsEmpty()) {
+ if (d->global_import_buf_.IsEmpty()) {
// Lazily initialize it.
- DCHECK_EQ(d->global_import_buf_ptr, nullptr);
- ab = v8::ArrayBuffer::New(d->isolate, GLOBAL_IMPORT_BUF_SIZE);
- d->global_import_buf.Reset(d->isolate, ab);
- d->global_import_buf_ptr = ab->GetContents().Data();
+ DCHECK_EQ(d->global_import_buf_ptr_, nullptr);
+ ab = v8::ArrayBuffer::New(d->isolate_, GLOBAL_IMPORT_BUF_SIZE);
+ d->global_import_buf_.Reset(d->isolate_, ab);
+ d->global_import_buf_ptr_ = ab->GetContents().Data();
} else {
- DCHECK(d->global_import_buf_ptr);
- ab = d->global_import_buf.Get(d->isolate);
+ DCHECK(d->global_import_buf_ptr_);
+ ab = d->global_import_buf_.Get(d->isolate_);
}
- data = d->global_import_buf_ptr;
+ data = d->global_import_buf_ptr_;
}
memcpy(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(
- d->isolate, reinterpret_cast<void*>(buf.alloc_ptr), buf.alloc_len,
+ d->isolate_, reinterpret_cast<void*>(buf.alloc_ptr), buf.alloc_len,
v8::ArrayBufferCreationMode::kInternalized);
auto view =
v8::Uint8Array::New(ab, buf.data_ptr - buf.alloc_ptr, buf.data_len);
@@ -248,16 +262,16 @@ static deno_buf GetContents(v8::Isolate* isolate,
return buf;
}
-// Sets the recv callback.
+// Sets the recv_ callback.
void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
- Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate, isolate);
+ DenoIsolate* d = FromIsolate(isolate);
+ DCHECK_EQ(d->isolate_, isolate);
v8::HandleScope handle_scope(isolate);
- if (!d->recv.IsEmpty()) {
- isolate->ThrowException(v8_str("libdeno.recv already called."));
+ if (!d->recv_.IsEmpty()) {
+ isolate->ThrowException(v8_str("libdeno.recv_ already called."));
return;
}
@@ -265,19 +279,19 @@ void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(v->IsFunction());
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
- d->recv.Reset(isolate, func);
+ d->recv_.Reset(isolate, func);
}
void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
- Deno* d = static_cast<Deno*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate, isolate);
+ DenoIsolate* d = FromIsolate(isolate);
+ DCHECK_EQ(d->isolate_, isolate);
- v8::Locker locker(d->isolate);
+ v8::Locker locker(d->isolate_);
v8::EscapableHandleScope handle_scope(isolate);
- CHECK_EQ(d->currentArgs, nullptr); // libdeno.send re-entry forbidden.
- int32_t req_id = d->next_req_id++;
+ CHECK_EQ(d->current_args_, nullptr); // libdeno.send re-entry forbidden.
+ int32_t req_id = d->next_req_id_++;
v8::Local<v8::Value> control_v = args[0];
CHECK(control_v->IsArrayBufferView());
@@ -294,16 +308,16 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK_EQ(args.Length(), 1);
}
- DCHECK_EQ(d->currentArgs, nullptr);
- d->currentArgs = &args;
+ DCHECK_EQ(d->current_args_, nullptr);
+ d->current_args_ = &args;
- d->cb(d->user_data, req_id, control, data);
+ d->cb_(d->user_data_, req_id, control, data);
- if (d->currentArgs == nullptr) {
+ if (d->current_args_ == nullptr) {
// This indicates that deno_repond() was called already.
} else {
// Asynchronous.
- d->currentArgs = nullptr;
+ 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()) {
@@ -315,12 +329,12 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
// Sets the global error handler.
void SetGlobalErrorHandler(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
- Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate, isolate);
+ DenoIsolate* d = FromIsolate(isolate);
+ DCHECK_EQ(d->isolate_, isolate);
v8::HandleScope handle_scope(isolate);
- if (!d->global_error_handler.IsEmpty()) {
+ if (!d->global_error_handler_.IsEmpty()) {
isolate->ThrowException(
v8_str("libdeno.setGlobalErrorHandler already called."));
return;
@@ -330,18 +344,18 @@ void SetGlobalErrorHandler(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(v->IsFunction());
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
- d->global_error_handler.Reset(isolate, func);
+ d->global_error_handler_.Reset(isolate, func);
}
// Sets the promise uncaught reject handler
void SetPromiseRejectHandler(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
- Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate, isolate);
+ DenoIsolate* d = FromIsolate(isolate);
+ DCHECK_EQ(d->isolate_, isolate);
v8::HandleScope handle_scope(isolate);
- if (!d->promise_reject_handler.IsEmpty()) {
+ if (!d->promise_reject_handler_.IsEmpty()) {
isolate->ThrowException(
v8_str("libdeno.setPromiseRejectHandler already called."));
return;
@@ -351,18 +365,18 @@ void SetPromiseRejectHandler(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(v->IsFunction());
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
- d->promise_reject_handler.Reset(isolate, func);
+ d->promise_reject_handler_.Reset(isolate, func);
}
// Sets the promise uncaught reject handler
void SetPromiseErrorExaminer(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
- Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate, isolate);
+ DenoIsolate* d = FromIsolate(isolate);
+ DCHECK_EQ(d->isolate_, isolate);
v8::HandleScope handle_scope(isolate);
- if (!d->promise_error_examiner.IsEmpty()) {
+ if (!d->promise_error_examiner_.IsEmpty()) {
isolate->ThrowException(
v8_str("libdeno.setPromiseErrorExaminer already called."));
return;
@@ -372,7 +386,7 @@ void SetPromiseErrorExaminer(const v8::FunctionCallbackInfo<v8::Value>& args) {
CHECK(v->IsFunction());
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
- d->promise_error_examiner.Reset(isolate, func);
+ d->promise_error_examiner_.Reset(isolate, func);
}
bool ExecuteV8StringSource(v8::Local<v8::Context> context,
@@ -502,145 +516,16 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
}
}
-void AddIsolate(Deno* d, v8::Isolate* isolate) {
- d->pending_promise_events = 0;
- d->next_req_id = 0;
- d->global_import_buf_ptr = nullptr;
- d->isolate = isolate;
+void DenoIsolate::AddIsolate(v8::Isolate* isolate) {
+ isolate_ = isolate;
// Leaving this code here because it will probably be useful later on, but
// disabling it now as I haven't got tests for the desired behavior.
// d->isolate->SetCaptureStackTraceForUncaughtExceptions(true);
// d->isolate->SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback);
// d->isolate->AddMessageListener(MessageCallback2);
// d->isolate->SetFatalErrorHandler(FatalErrorCallback2);
- d->isolate->SetPromiseRejectCallback(deno::PromiseRejectCallback);
- d->isolate->SetData(0, d);
+ isolate_->SetPromiseRejectCallback(deno::PromiseRejectCallback);
+ isolate_->SetData(0, this);
}
-class UserDataScope {
- Deno* deno;
- void* prev_data;
- void* data; // Not necessary; only for sanity checking.
-
- public:
- UserDataScope(Deno* deno_, void* data_) : deno(deno_), data(data_) {
- CHECK(deno->user_data == nullptr || deno->user_data == data_);
- prev_data = deno->user_data;
- deno->user_data = data;
- }
-
- ~UserDataScope() {
- CHECK(deno->user_data == data);
- deno->user_data = prev_data;
- }
-};
-
} // namespace deno
-
-extern "C" {
-
-void deno_init() {
- // v8::V8::InitializeICUDefaultLocation(argv[0]);
- // v8::V8::InitializeExternalStartupData(argv[0]);
- auto* p = v8::platform::CreateDefaultPlatform();
- v8::V8::InitializePlatform(p);
- v8::V8::Initialize();
-}
-
-const char* deno_v8_version() { return v8::V8::GetVersion(); }
-
-void deno_set_v8_flags(int* argc, char** argv) {
- v8::V8::SetFlagsFromCommandLine(argc, argv, true);
-}
-
-const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); }
-
-int deno_execute(Deno* d, void* user_data, const char* js_filename,
- const char* js_source) {
- deno::UserDataScope user_data_scope(d, user_data);
- auto* isolate = d->isolate;
- v8::Locker locker(isolate);
- v8::Isolate::Scope isolate_scope(isolate);
- v8::HandleScope handle_scope(isolate);
- auto context = d->context.Get(d->isolate);
- return deno::Execute(context, js_filename, js_source) ? 1 : 0;
-}
-
-int deno_respond(Deno* d, void* user_data, int32_t req_id, deno_buf buf) {
- if (d->currentArgs != nullptr) {
- // Synchronous response.
- auto ab = deno::ImportBuf(d, buf);
- d->currentArgs->GetReturnValue().Set(ab);
- d->currentArgs = nullptr;
- return 0;
- }
-
- // Asynchronous response.
- deno::UserDataScope user_data_scope(d, user_data);
- v8::Locker locker(d->isolate);
- v8::Isolate::Scope isolate_scope(d->isolate);
- v8::HandleScope handle_scope(d->isolate);
-
- auto context = d->context.Get(d->isolate);
- v8::Context::Scope context_scope(context);
-
- v8::TryCatch try_catch(d->isolate);
-
- deno::DeleteDataRef(d, req_id);
-
- auto recv = d->recv.Get(d->isolate);
- if (recv.IsEmpty()) {
- d->last_exception = "libdeno.recv has not been called.";
- return 1;
- }
-
- v8::Local<v8::Value> args[1];
- args[0] = deno::ImportBuf(d, buf);
- recv->Call(context->Global(), 1, args);
-
- if (try_catch.HasCaught()) {
- deno::HandleException(context, try_catch.Exception());
- return 1;
- }
-
- return 0;
-}
-
-void deno_check_promise_errors(Deno* d) {
- if (d->pending_promise_events > 0) {
- auto* isolate = d->isolate;
- v8::Locker locker(isolate);
- v8::Isolate::Scope isolate_scope(isolate);
- v8::HandleScope handle_scope(isolate);
-
- auto context = d->context.Get(d->isolate);
- v8::Context::Scope context_scope(context);
-
- v8::TryCatch try_catch(d->isolate);
- auto promise_error_examiner = d->promise_error_examiner.Get(d->isolate);
- if (promise_error_examiner.IsEmpty()) {
- d->last_exception =
- "libdeno.setPromiseErrorExaminer has not been called.";
- return;
- }
- v8::Local<v8::Value> args[0];
- auto result = promise_error_examiner->Call(context->Global(), 0, args);
- if (try_catch.HasCaught()) {
- deno::HandleException(context, try_catch.Exception());
- }
- d->pending_promise_events = 0; // reset
- if (!result->BooleanValue(context).FromJust()) {
- // Has uncaught promise reject error, exiting...
- exit(1);
- }
- }
-}
-
-void deno_delete(Deno* d) {
- d->isolate->Dispose();
- delete d;
-}
-
-void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); }
-
-} // extern "C"