diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2018-10-23 23:58:20 -0400 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2018-10-24 14:52:38 -0700 |
commit | 6afe94b3c855a8c486ce2a593cf2f8cac3b4d711 (patch) | |
tree | 0349632e80800a5a7b966a3fb91c4a4299ae393e /libdeno/api.cc | |
parent | fd68f85ce8cfbb036f0bc2c532f423d8ffa78289 (diff) |
libdeno: clean up
- Use a proper class for DenoIsolate.
- Move extern C stuff to api.cc
Diffstat (limited to 'libdeno/api.cc')
-rw-r--r-- | libdeno/api.cc | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/libdeno/api.cc b/libdeno/api.cc new file mode 100644 index 000000000..e01f95e82 --- /dev/null +++ b/libdeno/api.cc @@ -0,0 +1,162 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#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" + +#include "deno.h" +#include "internal.h" + +extern "C" { + +Deno* deno_new(deno_buf snapshot, deno_recv_cb cb) { + deno::DenoIsolate* d = new deno::DenoIsolate(snapshot, cb); + v8::Isolate::CreateParams params; + params.array_buffer_allocator = + v8::ArrayBuffer::Allocator::NewDefaultAllocator(); + params.external_references = deno::external_references; + + if (snapshot.data_ptr) { + params.snapshot_blob = &d->snapshot_; + } + + v8::Isolate* isolate = v8::Isolate::New(params); + d->AddIsolate(isolate); + + v8::Locker locker(isolate); + v8::Isolate::Scope isolate_scope(isolate); + { + v8::HandleScope handle_scope(isolate); + auto context = + v8::Context::New(isolate, nullptr, v8::MaybeLocal<v8::ObjectTemplate>(), + v8::MaybeLocal<v8::Value>(), + v8::DeserializeInternalFieldsCallback( + deno::DeserializeInternalFields, nullptr)); + d->context_.Reset(isolate, context); + } + + return reinterpret_cast<Deno*>(d); +} + +deno::DenoIsolate* unwrap(Deno* d_) { + return reinterpret_cast<deno::DenoIsolate*>(d_); +} + +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_) { + auto* d = unwrap(d_); + return d->last_exception_.c_str(); +} + +int deno_execute(Deno* d_, void* user_data_, const char* js_filename, + const char* js_source) { + auto* d = unwrap(d_); + 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) { + auto* d = unwrap(d_); + if (d->current_args_ != nullptr) { + // Synchronous response. + auto ab = deno::ImportBuf(d, buf); + d->current_args_->GetReturnValue().Set(ab); + d->current_args_ = 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_) { + auto* d = unwrap(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_) { + deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_); + d->isolate_->Dispose(); + delete d; +} + +void deno_terminate_execution(Deno* d_) { + deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_); + d->isolate_->TerminateExecution(); +} +} |