summaryrefslogtreecommitdiff
path: root/core/libdeno
diff options
context:
space:
mode:
Diffstat (limited to 'core/libdeno')
-rw-r--r--core/libdeno/.gn60
-rw-r--r--core/libdeno/BUILD.gn98
-rw-r--r--core/libdeno/api.cc254
-rw-r--r--core/libdeno/binding.cc597
-rw-r--r--core/libdeno/buffer.h140
m---------core/libdeno/build0
l---------core/libdeno/build_overrides1
l---------core/libdeno/buildtools1
-rw-r--r--core/libdeno/deno.h165
-rw-r--r--core/libdeno/exceptions.cc236
-rw-r--r--core/libdeno/exceptions.h27
-rw-r--r--core/libdeno/internal.h206
-rw-r--r--core/libdeno/libdeno_test.cc322
-rw-r--r--core/libdeno/libdeno_test.js271
-rw-r--r--core/libdeno/modules.cc223
-rw-r--r--core/libdeno/modules_test.cc426
-rw-r--r--core/libdeno/test.cc47
-rw-r--r--core/libdeno/test.h12
l---------core/libdeno/testing1
l---------core/libdeno/third_party1
l---------core/libdeno/tools1
l---------core/libdeno/v81
22 files changed, 0 insertions, 3090 deletions
diff --git a/core/libdeno/.gn b/core/libdeno/.gn
deleted file mode 100644
index 7916c47a7..000000000
--- a/core/libdeno/.gn
+++ /dev/null
@@ -1,60 +0,0 @@
-# This file is used by the GN meta build system to find the root of the source
-# tree and to set startup options. For documentation on the values set in this
-# file, run "gn help dotfile" at the command line.
-
-# The location of the build configuration file.
-buildconfig = "//build/config/BUILDCONFIG.gn"
-
-# These are the targets to check headers for by default. The files in targets
-# matching these patterns (see "gn help label_pattern" for format) will have
-# their includes checked for proper dependencies when you run either
-# "gn check" or "gn gen --check".
-check_targets = []
-
-default_args = {
- # Various global chrome args that are unrelated to deno.
- proprietary_codecs = false
- safe_browsing_mode = 0
- toolkit_views = false
- use_aura = false
- use_dbus = false
- use_gio = false
- use_glib = false
- use_ozone = false
- use_udev = false
-
- # To disable "use_atk" and other features that we don't need.
- is_desktop_linux = false
-
- # TODO(ry) We may want to turn on CFI at some point. Disabling for simplicity
- # for now. See http://clang.llvm.org/docs/ControlFlowIntegrity.html
- is_cfi = false
-
- # TODO(ry) Remove this so debug builds can link faster. Currently removing
- # this breaks cargo build in debug mode in OSX.
- is_component_build = false
-
- # Enable Jumbo build for a faster build.
- # https://chromium.googlesource.com/chromium/src/+/master/docs/jumbo.md
- use_jumbo_build = true
-
- symbol_level = 1
- treat_warnings_as_errors = true
-
- # https://cs.chromium.org/chromium/src/docs/ccache_mac.md
- clang_use_chrome_plugins = false
-
- v8_enable_gdbjit = false
- v8_enable_i18n_support = false
- v8_enable_shared_ro_heap = false # See #2624
- v8_imminent_deprecation_warnings = false
- v8_monolithic = false
- v8_untrusted_code_mitigations = false
- v8_use_external_startup_data = false
- v8_use_snapshot = true
- v8_postmortem_support = true # for https://github.com/nodejs/llnode/
-
- # We don't want to require downloading the binary executable
- # tools/clang/dsymutil.
- enable_dsyms = false
-}
diff --git a/core/libdeno/BUILD.gn b/core/libdeno/BUILD.gn
deleted file mode 100644
index 06e217c73..000000000
--- a/core/libdeno/BUILD.gn
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-import("//v8/gni/v8.gni")
-
-group("default") {
- testonly = true
- deps = [
- ":libdeno_static_lib",
- ":libdeno_test",
- ":v8",
- ]
-}
-
-config("deno_config") {
- include_dirs = [ "//v8" ] # This allows us to v8/src/base/ libraries.
- configs = [ "//v8:external_config" ]
- cflags = []
-
- if (is_debug) {
- defines = [ "DEBUG" ]
- }
-
- if (is_clang) {
- cflags += [
- "-fcolor-diagnostics",
- "-fansi-escape-codes",
- ]
- }
-
- if (is_debug && is_clang && !is_win) {
- cflags += [ "-glldb" ]
- }
-
- if (is_win) {
- # The `/Zl` ("omit default library name") flag makes the compiler produce
- # object files that can link with both the static and dynamic CRT.
- cflags += [ "/Zl" ]
- }
-}
-
-v8_source_set("v8") {
- deps = [
- "//v8:v8",
- "//v8:v8_libbase",
- "//v8:v8_libplatform",
- "//v8:v8_libsampler",
- ]
- configs = [ ":deno_config" ]
-}
-
-# Only functionality needed for libdeno_test and snapshot_creator
-# In particular no assets, no rust, no msg handlers.
-# Because snapshots are slow, it's important that snapshot_creator's
-# dependencies are minimal.
-v8_source_set("libdeno") {
- sources = [
- "api.cc",
- "binding.cc",
- "buffer.h",
- "deno.h",
- "exceptions.cc",
- "exceptions.h",
- "internal.h",
- "modules.cc",
- ]
- deps = [
- ":v8",
- ]
- configs = [ ":deno_config" ]
-}
-
-# The cargo-driven build links with libdeno to pull in all non-rust code.
-v8_static_library("libdeno_static_lib") {
- output_name = "libdeno"
- deps = [
- ":libdeno",
- "//build/config:shared_library_deps",
- ]
- configs = [ ":deno_config" ]
-}
-
-v8_executable("libdeno_test") {
- testonly = true
- sources = [
- "libdeno_test.cc",
- "modules_test.cc",
- "test.cc",
- ]
- deps = [
- ":libdeno",
- "//testing/gtest:gtest",
- ]
- data = [
- "libdeno_test.js",
- ]
- js_path = rebase_path(data[0])
- defines = [ "JS_PATH=\"$js_path\"" ]
- configs = [ ":deno_config" ]
-}
diff --git a/core/libdeno/api.cc b/core/libdeno/api.cc
deleted file mode 100644
index 149709819..000000000
--- a/core/libdeno/api.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <iostream>
-#include <string>
-
-#include "v8/include/libplatform/libplatform.h"
-#include "v8/include/v8.h"
-#include "v8/src/base/logging.h"
-
-#include "deno.h"
-#include "exceptions.h"
-#include "internal.h"
-
-extern "C" {
-
-Deno* deno_new_snapshotter(deno_config config) {
- CHECK(config.will_snapshot);
- // TODO(ry) Support loading snapshots before snapshotting.
- CHECK_NULL(config.load_snapshot.data_ptr);
- auto* creator = new v8::SnapshotCreator(deno::external_references);
- auto* isolate = creator->GetIsolate();
- auto* d = new deno::DenoIsolate(config);
- d->snapshot_creator_ = creator;
- d->AddIsolate(isolate);
- {
- v8::Locker locker(isolate);
- v8::Isolate::Scope isolate_scope(isolate);
- v8::HandleScope handle_scope(isolate);
- auto context = v8::Context::New(isolate);
- d->context_.Reset(isolate, context);
-
- creator->SetDefaultContext(context,
- v8::SerializeInternalFieldsCallback(
- deno::SerializeInternalFields, nullptr));
- deno::InitializeContext(isolate, context);
- }
- return reinterpret_cast<Deno*>(d);
-}
-
-Deno* deno_new(deno_config config) {
- if (config.will_snapshot) {
- return deno_new_snapshotter(config);
- }
- deno::DenoIsolate* d = new deno::DenoIsolate(config);
- v8::Isolate::CreateParams params;
- params.array_buffer_allocator = &deno::ArrayBufferAllocator::global();
- params.external_references = deno::external_references;
-
- if (config.load_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));
- if (!config.load_snapshot.data_ptr) {
- // If no snapshot is provided, we initialize the context with empty
- // main source code and source maps.
- deno::InitializeContext(isolate, context);
- }
- d->context_.Reset(isolate, context);
- }
-
- return reinterpret_cast<Deno*>(d);
-}
-
-void deno_lock(Deno* d_) {
- auto* d = deno::unwrap(d_);
- CHECK_NULL(d->locker_);
- d->locker_ = new v8::Locker(d->isolate_);
-}
-
-void deno_unlock(Deno* d_) {
- auto* d = deno::unwrap(d_);
- CHECK_NOT_NULL(d->locker_);
- delete d->locker_;
- d->locker_ = nullptr;
-}
-
-deno_snapshot deno_snapshot_new(Deno* d_) {
- auto* d = deno::unwrap(d_);
- CHECK_NOT_NULL(d->snapshot_creator_);
- d->ClearModules();
- d->context_.Reset();
-
- auto blob = d->snapshot_creator_->CreateBlob(
- v8::SnapshotCreator::FunctionCodeHandling::kKeep);
- d->has_snapshotted_ = true;
- return {reinterpret_cast<uint8_t*>(const_cast<char*>(blob.data)),
- blob.raw_size};
-}
-
-void deno_snapshot_delete(deno_snapshot snapshot) {
- delete[] snapshot.data_ptr;
-}
-
-static std::unique_ptr<v8::Platform> platform;
-
-void deno_init() {
- if (platform.get() == nullptr) {
- platform = v8::platform::NewDefaultPlatform();
- v8::V8::InitializePlatform(platform.get());
- v8::V8::Initialize();
- // TODO(ry) This makes WASM compile synchronously. Eventually we should
- // remove this to make it work asynchronously too. But that requires getting
- // PumpMessageLoop and RunMicrotasks setup correctly.
- // See https://github.com/denoland/deno/issues/2544
- const char* argv[3] = {"", "--no-wasm-async-compilation",
- "--harmony-top-level-await"};
- int argc = 3;
- v8::V8::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), false);
- }
-}
-
-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 = deno::unwrap(d_);
- if (d->last_exception_.length() > 0) {
- return d->last_exception_.c_str();
- } else {
- return nullptr;
- }
-}
-
-void deno_clear_last_exception(Deno* d_) {
- auto* d = deno::unwrap(d_);
- d->last_exception_.clear();
- d->last_exception_handle_.Reset();
-}
-
-void deno_execute(Deno* d_, void* user_data, const char* js_filename,
- const char* js_source) {
- auto* d = deno::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_);
- CHECK(!context.IsEmpty());
- deno::Execute(context, js_filename, js_source);
-}
-
-void deno_pinned_buf_delete(deno_pinned_buf* buf) {
- // The PinnedBuf destructor implicitly releases the ArrayBuffer reference.
- auto _ = deno::PinnedBuf(buf);
-}
-
-void deno_throw_exception(Deno* d_, const char* text) {
- auto* d = deno::unwrap(d_);
- auto* isolate = d->isolate_;
- isolate->ThrowException(deno::v8_str(text));
-}
-
-void deno_respond(Deno* d_, void* user_data, deno_op_id op_id, deno_buf buf) {
- auto* d = deno::unwrap(d_);
- if (d->current_args_ != nullptr) {
- // Synchronous response.
- // Note op_id is not passed back in the case of synchronous response.
- if (buf.data_ptr != nullptr && buf.data_len > 0) {
- auto ab = deno::ImportBuf(d, buf);
- d->current_args_->GetReturnValue().Set(ab);
- }
- d->current_args_ = nullptr;
- return;
- }
-
- // Asynchronous response.
- deno::UserDataScope user_data_scope(d, user_data);
- 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_);
-
- auto recv_ = d->recv_.Get(d->isolate_);
- if (recv_.IsEmpty()) {
- d->last_exception_ = "Deno.core.recv has not been called.";
- return;
- }
-
- v8::Local<v8::Value> args[2];
- int argc = 0;
-
- if (buf.data_ptr != nullptr) {
- args[0] = v8::Integer::New(d->isolate_, op_id);
- args[1] = deno::ImportBuf(d, buf);
- argc = 2;
- }
-
- auto v = recv_->Call(context, context->Global(), argc, args);
-
- if (try_catch.HasCaught()) {
- CHECK(v.IsEmpty());
- deno::HandleException(context, try_catch.Exception());
- }
-}
-
-void deno_check_promise_errors(Deno* d_) {
- auto* d = deno::unwrap(d_);
- if (d->pending_promise_map_.size() > 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);
-
- auto it = d->pending_promise_map_.begin();
- while (it != d->pending_promise_map_.end()) {
- auto error = it->second.Get(isolate);
- deno::HandleException(context, error);
- it = d->pending_promise_map_.erase(it);
- }
- }
-}
-
-void deno_delete(Deno* d_) {
- deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_);
- delete d;
-}
-
-void deno_terminate_execution(Deno* d_) {
- deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_);
- d->isolate_->TerminateExecution();
-}
-
-void deno_run_microtasks(Deno* d_, void* user_data) {
- deno::DenoIsolate* d = reinterpret_cast<deno::DenoIsolate*>(d_);
-
- deno::UserDataScope user_data_scope(d, user_data);
- v8::Locker locker(d->isolate_);
- v8::Isolate::Scope isolate_scope(d->isolate_);
- d->isolate_->RunMicrotasks();
-}
-}
diff --git a/core/libdeno/binding.cc b/core/libdeno/binding.cc
deleted file mode 100644
index 4785db3d0..000000000
--- a/core/libdeno/binding.cc
+++ /dev/null
@@ -1,597 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <algorithm>
-#include <iostream>
-#include <string>
-
-#ifdef _WIN32
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#include <io.h>
-#include <windows.h>
-#endif // _WIN32
-
-#include "v8/include/v8.h"
-#include "v8/src/base/logging.h"
-
-#include "deno.h"
-#include "exceptions.h"
-#include "internal.h"
-
-#define GLOBAL_IMPORT_BUF_SIZE 1024
-
-namespace deno {
-
-std::vector<InternalFieldData*> deserialized_data;
-
-void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
- v8::StartupData payload, void* data) {
- DCHECK_NULL(data);
- 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);
-}
-
-v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
- void* data) {
- DCHECK_NULL(data);
- InternalFieldData* embedder_field = static_cast<InternalFieldData*>(
- holder->GetAlignedPointerFromInternalField(index));
- if (embedder_field == nullptr) return {nullptr, 0};
- int size = sizeof(*embedder_field);
- char* payload = new char[size];
- // We simply use memcpy to serialize the content.
- memcpy(payload, embedder_field, size);
- return {payload, size};
-}
-
-// Extracts a C string from a v8::V8 Utf8Value.
-const char* ToCString(const v8::String::Utf8Value& value) {
- return *value ? *value : "<string conversion failed>";
-}
-
-void PromiseRejectCallback(v8::PromiseRejectMessage promise_reject_message) {
- auto* isolate = v8::Isolate::GetCurrent();
- DenoIsolate* d = static_cast<DenoIsolate*>(isolate->GetData(0));
- DCHECK_EQ(d->isolate_, isolate);
- v8::HandleScope handle_scope(d->isolate_);
- auto error = promise_reject_message.GetValue();
- auto context = d->context_.Get(d->isolate_);
- auto promise = promise_reject_message.GetPromise();
-
- v8::Context::Scope context_scope(context);
-
- int promise_id = promise->GetIdentityHash();
- switch (promise_reject_message.GetEvent()) {
- case v8::kPromiseRejectWithNoHandler:
- // Insert the error into the pending_promise_map_ using the promise's id
- // as the key.
- d->pending_promise_map_.emplace(std::piecewise_construct,
- std::make_tuple(promise_id),
- std::make_tuple(d->isolate_, error));
- break;
-
- case v8::kPromiseHandlerAddedAfterReject:
- d->pending_promise_map_.erase(promise_id);
- break;
-
- case v8::kPromiseRejectAfterResolved:
- break;
-
- case v8::kPromiseResolveAfterResolved:
- // Should not warn. See #1272
- break;
-
- default:
- CHECK(false && "unreachable");
- }
-}
-
-void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
- auto* isolate = args.GetIsolate();
- int argsLen = args.Length();
- if (argsLen < 1 || argsLen > 2) {
- ThrowInvalidArgument(isolate);
- }
- v8::HandleScope handle_scope(isolate);
- bool is_err = args.Length() >= 2 ? args[1]->BooleanValue(isolate) : false;
- FILE* file = is_err ? stderr : stdout;
-
-#ifdef _WIN32
- int fd = _fileno(file);
- if (fd < 0) return;
-
- HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
- if (h == INVALID_HANDLE_VALUE) return;
-
- DWORD mode;
- if (GetConsoleMode(h, &mode)) {
- // Print to Windows console. Since the Windows API generally doesn't support
- // UTF-8 encoded text, we have to use `WriteConsoleW()` which uses UTF-16.
- v8::String::Value str(isolate, args[0]);
- auto str_len = static_cast<size_t>(str.length());
- auto str_wchars = reinterpret_cast<WCHAR*>(*str);
-
- // WriteConsoleW has some limit to how many characters can be written at
- // once, which is unspecified but low enough to be encountered in practice.
- // Therefore we break up the write into chunks of 8kb if necessary.
- size_t chunk_start = 0;
- while (chunk_start < str_len) {
- size_t chunk_end = std::min(chunk_start + 8192, str_len);
-
- // Do not break in the middle of a surrogate pair. Note that `chunk_end`
- // points to the start of the next chunk, so we check whether it contains
- // the second half of a surrogate pair (a.k.a. "low surrogate").
- if (chunk_end < str_len && str_wchars[chunk_end] >= 0xdc00 &&
- str_wchars[chunk_end] <= 0xdfff) {
- --chunk_end;
- }
-
- // Write to the console.
- DWORD chunk_len = static_cast<DWORD>(chunk_end - chunk_start);
- DWORD _;
- WriteConsoleW(h, &str_wchars[chunk_start], chunk_len, &_, nullptr);
-
- chunk_start = chunk_end;
- }
- return;
- }
-#endif // _WIN32
-
- v8::String::Utf8Value str(isolate, args[0]);
- fwrite(*str, sizeof(**str), str.length(), file);
- fflush(file);
-}
-
-void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(args.Length(), 1);
- auto* isolate = args.GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- auto context = d->context_.Get(d->isolate_);
- v8::HandleScope handle_scope(isolate);
- auto json_string = EncodeExceptionAsJSON(context, args[0]);
- args.GetReturnValue().Set(v8_str(json_string.c_str()));
-}
-
-v8::Local<v8::Uint8Array> ImportBuf(DenoIsolate* d, deno_buf buf) {
- if (buf.data_ptr == nullptr) {
- return v8::Local<v8::Uint8Array>();
- }
-
- // To avoid excessively allocating new ArrayBuffers, we try to reuse a single
- // global ArrayBuffer. The caveat is that users must extract data from it
- // before the next tick. We only do this for ArrayBuffers less than 1024
- // bytes.
- v8::Local<v8::ArrayBuffer> ab;
- 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);
- data = ab->GetBackingStore()->Data();
- } else {
- // Fast case. We reuse the global ArrayBuffer.
- if (d->global_import_buf_.IsEmpty()) {
- // Lazily initialize it.
- DCHECK_NULL(d->global_import_buf_ptr_);
- ab = v8::ArrayBuffer::New(d->isolate_, GLOBAL_IMPORT_BUF_SIZE);
- d->global_import_buf_.Reset(d->isolate_, ab);
- d->global_import_buf_ptr_ = ab->GetBackingStore()->Data();
- } else {
- DCHECK(d->global_import_buf_ptr_);
- ab = d->global_import_buf_.Get(d->isolate_);
- }
- 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;
-}
-
-// Sets the recv_ callback.
-void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Isolate* isolate = args.GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- DCHECK_EQ(d->isolate_, isolate);
-
- v8::HandleScope handle_scope(isolate);
-
- if (!d->recv_.IsEmpty()) {
- isolate->ThrowException(v8_str("Deno.core.recv already called."));
- return;
- }
-
- v8::Local<v8::Value> v = args[0];
- CHECK(v->IsFunction());
- v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
-
- d->recv_.Reset(isolate, func);
-}
-
-void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Isolate* isolate = args.GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- DCHECK_EQ(d->isolate_, isolate);
-
- v8::HandleScope handle_scope(isolate);
-
- deno_buf control = {nullptr, 0};
-
- int32_t op_id = 0;
- if (args[0]->IsInt32()) {
- auto context = d->context_.Get(isolate);
- op_id = args[0]->Int32Value(context).FromJust();
- }
-
- if (args[1]->IsArrayBufferView()) {
- auto view = v8::Local<v8::ArrayBufferView>::Cast(args[1]);
- auto data =
- reinterpret_cast<uint8_t*>(view->Buffer()->GetBackingStore()->Data());
- control = {data + view->ByteOffset(), view->ByteLength()};
- }
-
- PinnedBuf zero_copy =
- args[2]->IsArrayBufferView()
- ? PinnedBuf(v8::Local<v8::ArrayBufferView>::Cast(args[2]))
- : PinnedBuf();
-
- DCHECK_NULL(d->current_args_);
- d->current_args_ = &args;
-
- d->recv_cb_(d->user_data_, op_id, control, zero_copy.IntoRaw());
-
- if (d->current_args_ == nullptr) {
- // This indicates that deno_repond() was called already.
- } else {
- // Asynchronous.
- d->current_args_ = nullptr;
- }
-}
-
-v8::ScriptOrigin ModuleOrigin(v8::Isolate* isolate,
- v8::Local<v8::Value> resource_name) {
- return v8::ScriptOrigin(resource_name, v8::Local<v8::Integer>(),
- v8::Local<v8::Integer>(), v8::Local<v8::Boolean>(),
- v8::Local<v8::Integer>(), v8::Local<v8::Value>(),
- v8::Local<v8::Boolean>(), v8::Local<v8::Boolean>(),
- v8::True(isolate));
-}
-
-deno_mod DenoIsolate::RegisterModule(bool main, const char* name,
- const char* source) {
- v8::Isolate::Scope isolate_scope(isolate_);
- v8::Locker locker(isolate_);
- v8::HandleScope handle_scope(isolate_);
- auto context = context_.Get(isolate_);
- v8::Context::Scope context_scope(context);
-
- v8::Local<v8::String> name_str = v8_str(name);
- v8::Local<v8::String> source_str = v8_str(source);
-
- auto origin = ModuleOrigin(isolate_, name_str);
- v8::ScriptCompiler::Source source_(source_str, origin);
-
- v8::TryCatch try_catch(isolate_);
-
- auto maybe_module = v8::ScriptCompiler::CompileModule(isolate_, &source_);
-
- if (try_catch.HasCaught()) {
- CHECK(maybe_module.IsEmpty());
- HandleException(context, try_catch.Exception());
- return 0;
- }
-
- auto module = maybe_module.ToLocalChecked();
-
- int id = module->GetIdentityHash();
-
- std::vector<std::string> import_specifiers;
-
- for (int i = 0; i < module->GetModuleRequestsLength(); ++i) {
- v8::Local<v8::String> specifier = module->GetModuleRequest(i);
- v8::String::Utf8Value specifier_utf8(isolate_, specifier);
- import_specifiers.push_back(*specifier_utf8);
- }
-
- mods_.emplace(
- std::piecewise_construct, std::make_tuple(id),
- std::make_tuple(isolate_, module, main, name, import_specifiers));
- mods_by_name_[name] = id;
-
- return id;
-}
-
-void Shared(v8::Local<v8::Name> property,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- v8::Isolate* isolate = info.GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- DCHECK_EQ(d->isolate_, isolate);
- v8::Locker locker(d->isolate_);
- v8::EscapableHandleScope handle_scope(isolate);
- if (d->shared_.data_ptr == nullptr) {
- return;
- }
- v8::Local<v8::SharedArrayBuffer> ab;
- if (d->shared_ab_.IsEmpty()) {
- // Lazily initialize the persistent external ArrayBuffer.
- ab = v8::SharedArrayBuffer::New(isolate, d->shared_.data_ptr,
- d->shared_.data_len,
- v8::ArrayBufferCreationMode::kExternalized);
- d->shared_ab_.Reset(isolate, ab);
- }
- auto shared_ab = d->shared_ab_.Get(isolate);
- info.GetReturnValue().Set(shared_ab);
-}
-
-void DenoIsolate::ClearModules() {
- for (auto it = mods_.begin(); it != mods_.end(); it++) {
- it->second.handle.Reset();
- }
- mods_.clear();
- mods_by_name_.clear();
-}
-
-bool Execute(v8::Local<v8::Context> context, const char* js_filename,
- const char* js_source) {
- auto* isolate = context->GetIsolate();
- v8::Isolate::Scope isolate_scope(isolate);
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context);
-
- auto source = v8_str(js_source);
- auto name = v8_str(js_filename);
-
- v8::TryCatch try_catch(isolate);
-
- v8::ScriptOrigin origin(name);
-
- auto script = v8::Script::Compile(context, source, &origin);
-
- if (script.IsEmpty()) {
- DCHECK(try_catch.HasCaught());
- HandleException(context, try_catch.Exception());
- return false;
- }
-
- auto result = script.ToLocalChecked()->Run(context);
-
- if (result.IsEmpty()) {
- DCHECK(try_catch.HasCaught());
- HandleException(context, try_catch.Exception());
- return false;
- }
-
- return true;
-}
-
-static inline v8::Local<v8::Boolean> v8_bool(bool v) {
- return v8::Boolean::New(v8::Isolate::GetCurrent(), v);
-}
-
-void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Isolate* isolate = args.GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- v8::EscapableHandleScope handleScope(isolate);
- auto context = d->context_.Get(isolate);
- v8::Context::Scope context_scope(context);
-
- if (!(args[0]->IsString())) {
- ThrowInvalidArgument(isolate);
- return;
- }
-
- auto source = args[0].As<v8::String>();
-
- auto output = v8::Array::New(isolate, 2);
- /**
- * output[0] = result
- * output[1] = ErrorInfo | null
- * ErrorInfo = {
- * thrown: Error | any,
- * isNativeError: boolean,
- * isCompileError: boolean,
- * }
- */
-
- v8::TryCatch try_catch(isolate);
-
- auto name = v8_str("<unknown>");
- v8::ScriptOrigin origin(name);
- auto script = v8::Script::Compile(context, source, &origin);
-
- if (script.IsEmpty()) {
- CHECK(try_catch.HasCaught());
- auto exception = try_catch.Exception();
-
- CHECK(output->Set(context, 0, v8::Null(isolate)).FromJust());
-
- auto errinfo_obj = v8::Object::New(isolate);
- CHECK(errinfo_obj->Set(context, v8_str("isCompileError"), v8_bool(true))
- .FromJust());
- CHECK(errinfo_obj
- ->Set(context, v8_str("isNativeError"),
- v8_bool(exception->IsNativeError()))
- .FromJust());
- CHECK(errinfo_obj->Set(context, v8_str("thrown"), exception).FromJust());
-
- CHECK(output->Set(context, 1, errinfo_obj).FromJust());
-
- args.GetReturnValue().Set(output);
- return;
- }
-
- auto result = script.ToLocalChecked()->Run(context);
-
- if (result.IsEmpty()) {
- CHECK(try_catch.HasCaught());
- auto exception = try_catch.Exception();
-
- CHECK(output->Set(context, 0, v8::Null(isolate)).FromJust());
-
- auto errinfo_obj = v8::Object::New(isolate);
- CHECK(errinfo_obj->Set(context, v8_str("isCompileError"), v8_bool(false))
- .FromJust());
- CHECK(errinfo_obj
- ->Set(context, v8_str("isNativeError"),
- v8_bool(exception->IsNativeError()))
- .FromJust());
- CHECK(errinfo_obj->Set(context, v8_str("thrown"), exception).FromJust());
-
- CHECK(output->Set(context, 1, errinfo_obj).FromJust());
-
- args.GetReturnValue().Set(output);
- return;
- }
-
- CHECK(output->Set(context, 0, result.ToLocalChecked()).FromJust());
- CHECK(output->Set(context, 1, v8::Null(isolate)).FromJust());
- args.GetReturnValue().Set(output);
-}
-
-void QueueMicrotask(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Isolate* isolate = args.GetIsolate();
-
- if (!(args[0]->IsFunction())) {
- ThrowInvalidArgument(isolate);
- return;
- }
- isolate->EnqueueMicrotask(args[0].As<v8::Function>());
-}
-
-void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context);
-
- auto global = context->Global();
-
- auto deno_val = v8::Object::New(isolate);
- CHECK(global->Set(context, deno::v8_str("Deno"), deno_val).FromJust());
-
- auto core_val = v8::Object::New(isolate);
- CHECK(deno_val->Set(context, deno::v8_str("core"), core_val).FromJust());
-
- auto print_tmpl = v8::FunctionTemplate::New(isolate, Print);
- auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
- CHECK(core_val->Set(context, deno::v8_str("print"), print_val).FromJust());
-
- auto recv_tmpl = v8::FunctionTemplate::New(isolate, Recv);
- auto recv_val = recv_tmpl->GetFunction(context).ToLocalChecked();
- CHECK(core_val->Set(context, deno::v8_str("recv"), recv_val).FromJust());
-
- auto send_tmpl = v8::FunctionTemplate::New(isolate, Send);
- auto send_val = send_tmpl->GetFunction(context).ToLocalChecked();
- CHECK(core_val->Set(context, deno::v8_str("send"), send_val).FromJust());
-
- auto eval_context_tmpl = v8::FunctionTemplate::New(isolate, EvalContext);
- auto eval_context_val =
- eval_context_tmpl->GetFunction(context).ToLocalChecked();
- CHECK(core_val->Set(context, deno::v8_str("evalContext"), eval_context_val)
- .FromJust());
-
- auto error_to_json_tmpl = v8::FunctionTemplate::New(isolate, ErrorToJSON);
- auto error_to_json_val =
- error_to_json_tmpl->GetFunction(context).ToLocalChecked();
- CHECK(core_val->Set(context, deno::v8_str("errorToJSON"), error_to_json_val)
- .FromJust());
-
- CHECK(core_val->SetAccessor(context, deno::v8_str("shared"), Shared)
- .FromJust());
-
- // Direct bindings on `window`.
- auto queue_microtask_tmpl =
- v8::FunctionTemplate::New(isolate, QueueMicrotask);
- auto queue_microtask_val =
- queue_microtask_tmpl->GetFunction(context).ToLocalChecked();
- CHECK(
- global->Set(context, deno::v8_str("queueMicrotask"), queue_microtask_val)
- .FromJust());
-}
-
-void MessageCallback(v8::Local<v8::Message> message,
- v8::Local<v8::Value> data) {
- auto* isolate = message->GetIsolate();
- DenoIsolate* d = static_cast<DenoIsolate*>(isolate->GetData(0));
-
- v8::HandleScope handle_scope(isolate);
- auto context = d->context_.Get(isolate);
- HandleExceptionMessage(context, message);
-}
-
-void HostInitializeImportMetaObjectCallback(v8::Local<v8::Context> context,
- v8::Local<v8::Module> module,
- v8::Local<v8::Object> meta) {
- auto* isolate = context->GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- v8::Isolate::Scope isolate_scope(isolate);
-
- CHECK(!module.IsEmpty());
-
- deno_mod id = module->GetIdentityHash();
- CHECK_NE(id, 0);
-
- auto* info = d->GetModuleInfo(id);
-
- const char* url = info->name.c_str();
- const bool main = info->main;
-
- meta->CreateDataProperty(context, v8_str("url"), v8_str(url)).ToChecked();
- meta->CreateDataProperty(context, v8_str("main"), v8_bool(main)).ToChecked();
-}
-
-v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallback(
- v8::Local<v8::Context> context, v8::Local<v8::ScriptOrModule> referrer,
- v8::Local<v8::String> specifier) {
- auto* isolate = context->GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- v8::Isolate::Scope isolate_scope(isolate);
- v8::Context::Scope context_scope(context);
- v8::EscapableHandleScope handle_scope(isolate);
-
- v8::String::Utf8Value specifier_str(isolate, specifier);
-
- auto referrer_name = referrer->GetResourceName();
- v8::String::Utf8Value referrer_name_str(isolate, referrer_name);
-
- // TODO(ry) I'm not sure what HostDefinedOptions is for or if we're ever going
- // to use it. For now we check that it is not used. This check may need to be
- // changed in the future.
- auto host_defined_options = referrer->GetHostDefinedOptions();
- CHECK_EQ(host_defined_options->Length(), 0);
-
- v8::Local<v8::Promise::Resolver> resolver =
- v8::Promise::Resolver::New(context).ToLocalChecked();
-
- deno_dyn_import_id import_id = d->next_dyn_import_id_++;
-
- d->dyn_import_map_.emplace(std::piecewise_construct,
- std::make_tuple(import_id),
- std::make_tuple(d->isolate_, resolver));
-
- d->dyn_import_cb_(d->user_data_, *specifier_str, *referrer_name_str,
- import_id);
-
- auto promise = resolver->GetPromise();
- return handle_scope.Escape(promise);
-}
-
-void DenoIsolate::AddIsolate(v8::Isolate* isolate) {
- isolate_ = isolate;
- isolate_->SetCaptureStackTraceForUncaughtExceptions(
- true, 10, v8::StackTrace::kDetailed);
- isolate_->SetPromiseRejectCallback(deno::PromiseRejectCallback);
- isolate_->SetData(0, this);
- isolate_->AddMessageListener(MessageCallback);
- isolate->SetHostInitializeImportMetaObjectCallback(
- HostInitializeImportMetaObjectCallback);
- isolate->SetHostImportModuleDynamicallyCallback(
- HostImportModuleDynamicallyCallback);
-}
-
-} // namespace deno
diff --git a/core/libdeno/buffer.h b/core/libdeno/buffer.h
deleted file mode 100644
index 4f641f270..000000000
--- a/core/libdeno/buffer.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#ifndef BUFFER_H_
-#define BUFFER_H_
-
-// Cpplint bans the use of <mutex> because it duplicates functionality in
-// chromium //base. However Deno doensn't use that, so suppress that lint.
-#include <memory>
-#include <mutex> // NOLINT
-#include <string>
-#include <unordered_map>
-#include <utility>
-
-#include "v8/include/v8.h"
-#include "v8/src/base/logging.h"
-
-namespace deno {
-
-class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
- public:
- static ArrayBufferAllocator& global() {
- static ArrayBufferAllocator global_instance;
- return global_instance;
- }
-
- void* Allocate(size_t length) override { return new uint8_t[length](); }
-
- void* AllocateUninitialized(size_t length) override {
- return new uint8_t[length];
- }
-
- void Free(void* data, size_t length) override { Unref(data); }
-
- private:
- friend class PinnedBuf;
-
- void Ref(void* data) {
- std::lock_guard<std::mutex> lock(ref_count_map_mutex_);
- // Note:
- // - `unordered_map::insert(make_pair(key, value))` returns the existing
- // item if the key, already exists in the map, otherwise it creates an
- // new entry with `value`.
- // - Buffers not in the map have an implicit reference count of one.
- auto entry = ref_count_map_.insert(std::make_pair(data, 1)).first;
- ++entry->second;
- }
-
- void Unref(void* data) {
- {
- std::lock_guard<std::mutex> lock(ref_count_map_mutex_);
- auto entry = ref_count_map_.find(data);
- if (entry == ref_count_map_.end()) {
- // Buffers not in the map have an implicit ref count of one. After
- // dereferencing there are no references left, so we delete the buffer.
- } else if (--entry->second == 0) {
- // The reference count went to zero, so erase the map entry and free the
- // buffer.
- ref_count_map_.erase(entry);
- } else {
- // After decreasing the reference count the buffer still has references
- // left, so we leave the pin in place.
- return;
- }
- delete[] reinterpret_cast<uint8_t*>(data);
- }
- }
-
- private:
- ArrayBufferAllocator() {}
-
- ~ArrayBufferAllocator() {
- // TODO(pisciaureus): Enable this check. It currently fails sometimes
- // because the compiler worker isolate never actually exits, so when the
- // process exits this isolate still holds on to some buffers.
- // CHECK(ref_count_map_.empty());
- }
-
- std::unordered_map<void*, size_t> ref_count_map_;
- std::mutex ref_count_map_mutex_;
-};
-
-class PinnedBuf {
- struct Unref {
- // This callback gets called from the Pin destructor.
- void operator()(void* ptr) { ArrayBufferAllocator::global().Unref(ptr); }
- };
- // The Pin is a unique (non-copyable) smart pointer which automatically
- // unrefs the referenced ArrayBuffer in its destructor.
- using Pin = std::unique_ptr<void, Unref>;
-
- uint8_t* data_ptr_;
- size_t data_len_;
- Pin pin_;
-
- public:
- // PinnedBuf::Raw is a POD struct with the same memory layout as the PinBuf
- // itself. It is used to move a PinnedBuf between C and Rust.
- struct Raw {
- uint8_t* data_ptr;
- size_t data_len;
- void* pin;
- };
-
- PinnedBuf() : data_ptr_(nullptr), data_len_(0), pin_() {}
-
- explicit PinnedBuf(v8::Local<v8::ArrayBufferView> view) {
- auto buf = view->Buffer()->GetBackingStore()->Data();
- ArrayBufferAllocator::global().Ref(buf);
-
- data_ptr_ = reinterpret_cast<uint8_t*>(buf) + view->ByteOffset();
- data_len_ = view->ByteLength();
- pin_ = Pin(buf);
- }
-
- // This constructor recreates a PinnedBuf that has previously been converted
- // to a PinnedBuf::Raw using the IntoRaw() method. This is a move operation;
- // the Raw struct is emptied in the process.
- explicit PinnedBuf(Raw* raw)
- : data_ptr_(raw->data_ptr), data_len_(raw->data_len), pin_(raw->pin) {
- raw->data_ptr = nullptr;
- raw->data_len = 0;
- raw->pin = nullptr;
- }
-
- // The IntoRaw() method converts the PinnedBuf to a PinnedBuf::Raw so it's
- // ownership can be moved to Rust. The source PinnedBuf is emptied in the
- // process, but the pinned ArrayBuffer is not dereferenced. In order to not
- // leak it, the raw struct must eventually be turned back into a PinnedBuf
- // using the constructor above.
- Raw IntoRaw() {
- Raw raw{
- .data_ptr = data_ptr_, .data_len = data_len_, .pin = pin_.release()};
- data_ptr_ = nullptr;
- data_len_ = 0;
- return raw;
- }
-};
-
-} // namespace deno
-
-#endif // BUFFER_H_
diff --git a/core/libdeno/build b/core/libdeno/build
deleted file mode 160000
-Subproject 6af664c48ed657b89e99a9a8692dc15d7f7a6d9
diff --git a/core/libdeno/build_overrides b/core/libdeno/build_overrides
deleted file mode 120000
index f1aca1a07..000000000
--- a/core/libdeno/build_overrides
+++ /dev/null
@@ -1 +0,0 @@
-v8/build_overrides \ No newline at end of file
diff --git a/core/libdeno/buildtools b/core/libdeno/buildtools
deleted file mode 120000
index c5b1c451c..000000000
--- a/core/libdeno/buildtools
+++ /dev/null
@@ -1 +0,0 @@
-v8/buildtools \ No newline at end of file
diff --git a/core/libdeno/deno.h b/core/libdeno/deno.h
deleted file mode 100644
index 1beabf5b4..000000000
--- a/core/libdeno/deno.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#ifndef DENO_H_
-#define DENO_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "buffer.h"
-
-// Neither Rust nor Go support calling directly into C++ functions, therefore
-// the public interface to libdeno is done in C.
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef deno::PinnedBuf::Raw deno_pinned_buf;
-
-// Data that gets transmitted.
-typedef struct {
- uint8_t* data_ptr;
- size_t data_len;
-} deno_buf;
-
-typedef struct {
- uint8_t* data_ptr;
- size_t data_len;
-} deno_snapshot;
-
-typedef struct deno_s Deno;
-
-typedef uint32_t deno_op_id;
-
-// A callback to receive a message from a Deno.core.send() javascript call.
-// control_buf is valid for only for the lifetime of this callback.
-// data_buf is valid until deno_respond() is called.
-//
-// op_id corresponds to the first argument of Deno.core.send().
-// op_id is an extra user-defined integer valued which is not interpreted by
-// libdeno.
-//
-// control_buf corresponds to the second argument of Deno.core.send().
-//
-// zero_copy_buf corresponds to the third argument of Deno.core.send().
-// The user must call deno_pinned_buf_delete on each zero_copy_buf received.
-typedef void (*deno_recv_cb)(void* user_data, deno_op_id op_id,
- deno_buf control_buf,
- deno_pinned_buf zero_copy_buf);
-
-typedef int deno_dyn_import_id;
-// Called when dynamic import is called in JS: import('foo')
-// Embedder must call deno_dyn_import_done() with the specified id and
-// the module.
-typedef void (*deno_dyn_import_cb)(void* user_data, const char* specifier,
- const char* referrer, deno_dyn_import_id id);
-
-void deno_init();
-const char* deno_v8_version();
-void deno_set_v8_flags(int* argc, char** argv);
-
-typedef struct {
- int will_snapshot; // Default 0. If calling deno_snapshot_new 1.
- deno_snapshot load_snapshot; // A startup snapshot to use.
- deno_buf shared; // Shared buffer to be mapped to libdeno.shared
- deno_recv_cb recv_cb; // Maps to Deno.core.send() calls.
- deno_dyn_import_cb dyn_import_cb;
-} deno_config;
-
-// Create a new deno isolate.
-// Warning: If config.will_snapshot is set, deno_snapshot_new() must be called
-// or an error will result.
-Deno* deno_new(deno_config config);
-void deno_delete(Deno* d);
-
-// Generate a snapshot. The resulting buf can be used in as the load_snapshot
-// member in deno_confg.
-// When calling this function, the caller must have created the isolate "d" with
-// "will_snapshot" set to 1.
-// The caller must free the returned data with deno_snapshot_delete().
-deno_snapshot deno_snapshot_new(Deno* d);
-
-// Only for use with data returned from deno_snapshot_new.
-void deno_snapshot_delete(deno_snapshot);
-
-void deno_lock(Deno* d);
-void deno_unlock(Deno* d);
-
-// Compile and execute a traditional JavaScript script that does not use
-// module import statements.
-// If it succeeded deno_last_exception() will return NULL.
-void deno_execute(Deno* d, void* user_data, const char* js_filename,
- const char* js_source);
-
-// deno_respond sends one message back for every deno_recv_cb made.
-//
-// If this is called during deno_recv_cb, the issuing Deno.core.send() in
-// javascript will synchronously return the specified buf as an ArrayBuffer (or
-// null if buf is empty).
-//
-// If this is called after deno_recv_cb has returned, the deno_respond
-// will call into the JS callback specified by Deno.core.recv().
-//
-// (Ideally, but not currently: After calling deno_respond(), the caller no
-// longer owns `buf` and must not use it; deno_respond() is responsible for
-// releasing its memory.)
-//
-// op_id is an extra user-defined integer valued which is not currently
-// interpreted by libdeno. But it should probably correspond to the op_id in
-// deno_recv_cb.
-//
-// If a JS exception was encountered, deno_last_exception() will be non-NULL.
-void deno_respond(Deno* d, void* user_data, deno_op_id op_id, deno_buf buf);
-
-void deno_throw_exception(Deno* d, const char* text);
-
-// consumes zero_copy
-void deno_pinned_buf_delete(deno_pinned_buf* buf);
-
-void deno_check_promise_errors(Deno* d);
-
-// Returns a cstring pointer to the exception.
-// Rust side must NOT assert ownership.
-const char* deno_last_exception(Deno* d);
-
-// Clears last exception.
-// Rust side must NOT hold pointer to exception string when called.
-void deno_clear_last_exception(Deno* d_);
-
-void deno_terminate_execution(Deno* d);
-
-void deno_run_microtasks(Deno* d, void* user_data);
-// Module API
-
-typedef int deno_mod;
-
-// Returns zero on error - check deno_last_exception().
-deno_mod deno_mod_new(Deno* d, bool main, const char* name, const char* source);
-
-size_t deno_mod_imports_len(Deno* d, deno_mod id);
-
-// Returned pointer is valid for the lifetime of the Deno isolate "d".
-const char* deno_mod_imports_get(Deno* d, deno_mod id, size_t index);
-
-typedef deno_mod (*deno_resolve_cb)(void* user_data, const char* specifier,
- deno_mod referrer);
-
-// If it succeeded deno_last_exception() will return NULL.
-void deno_mod_instantiate(Deno* d, void* user_data, deno_mod id,
- deno_resolve_cb cb);
-
-// If it succeeded deno_last_exception() will return NULL.
-void deno_mod_evaluate(Deno* d, void* user_data, deno_mod id);
-
-// Call exactly once for every deno_dyn_import_cb.
-// Note this call will execute JS.
-// Either mod_id is zero and error_str is not null OR mod_id is valid and
-// error_str is null.
-// TODO(ry) The errors arising from dynamic import are not exactly the same as
-// those arising from ops in Deno.
-void deno_dyn_import_done(Deno* d, void* user_data, deno_dyn_import_id id,
- deno_mod mod_id, const char* error_str);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-#endif // DENO_H_
diff --git a/core/libdeno/exceptions.cc b/core/libdeno/exceptions.cc
deleted file mode 100644
index 7f622da80..000000000
--- a/core/libdeno/exceptions.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include "exceptions.h"
-#include <string>
-#include "internal.h"
-
-namespace deno {
-
-v8::Local<v8::Object> EncodeMessageAsObject(v8::Local<v8::Context> context,
- v8::Local<v8::Message> message) {
- auto* isolate = context->GetIsolate();
- v8::EscapableHandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context);
-
- auto stack_trace = message->GetStackTrace();
-
- // Encode the exception into a JS object, which we will then turn into JSON.
- auto json_obj = v8::Object::New(isolate);
- auto exception_str = message->Get();
- CHECK(json_obj->Set(context, v8_str("message"), exception_str).FromJust());
-
- auto maybe_source_line = message->GetSourceLine(context);
- if (!maybe_source_line.IsEmpty()) {
- CHECK(json_obj
- ->Set(context, v8_str("sourceLine"),
- maybe_source_line.ToLocalChecked())
- .FromJust());
- }
-
- CHECK(json_obj
- ->Set(context, v8_str("scriptResourceName"),
- message->GetScriptResourceName())
- .FromJust());
-
- auto maybe_line_number = message->GetLineNumber(context);
- if (maybe_line_number.IsJust()) {
- CHECK(json_obj
- ->Set(context, v8_str("lineNumber"),
- v8::Integer::New(isolate, maybe_line_number.FromJust()))
- .FromJust());
- }
-
- CHECK(json_obj
- ->Set(context, v8_str("startPosition"),
- v8::Integer::New(isolate, message->GetStartPosition()))
- .FromJust());
-
- CHECK(json_obj
- ->Set(context, v8_str("endPosition"),
- v8::Integer::New(isolate, message->GetEndPosition()))
- .FromJust());
-
- CHECK(json_obj
- ->Set(context, v8_str("errorLevel"),
- v8::Integer::New(isolate, message->ErrorLevel()))
- .FromJust());
-
- auto maybe_start_column = message->GetStartColumn(context);
- if (maybe_start_column.IsJust()) {
- auto start_column =
- v8::Integer::New(isolate, maybe_start_column.FromJust());
- CHECK(
- json_obj->Set(context, v8_str("startColumn"), start_column).FromJust());
- }
-
- auto maybe_end_column = message->GetEndColumn(context);
- if (maybe_end_column.IsJust()) {
- auto end_column = v8::Integer::New(isolate, maybe_end_column.FromJust());
- CHECK(json_obj->Set(context, v8_str("endColumn"), end_column).FromJust());
- }
-
- CHECK(json_obj
- ->Set(context, v8_str("isSharedCrossOrigin"),
- v8::Boolean::New(isolate, message->IsSharedCrossOrigin()))
- .FromJust());
-
- CHECK(json_obj
- ->Set(context, v8_str("isOpaque"),
- v8::Boolean::New(isolate, message->IsOpaque()))
- .FromJust());
-
- v8::Local<v8::Array> frames;
- if (!stack_trace.IsEmpty()) {
- uint32_t count = static_cast<uint32_t>(stack_trace->GetFrameCount());
- frames = v8::Array::New(isolate, count);
-
- for (uint32_t i = 0; i < count; ++i) {
- auto frame = stack_trace->GetFrame(isolate, i);
- auto frame_obj = v8::Object::New(isolate);
- CHECK(frames->Set(context, i, frame_obj).FromJust());
- auto line = v8::Integer::New(isolate, frame->GetLineNumber());
- auto column = v8::Integer::New(isolate, frame->GetColumn());
- CHECK(frame_obj->Set(context, v8_str("line"), line).FromJust());
- CHECK(frame_obj->Set(context, v8_str("column"), column).FromJust());
-
- auto function_name = frame->GetFunctionName();
- if (!function_name.IsEmpty()) {
- CHECK(frame_obj->Set(context, v8_str("functionName"), function_name)
- .FromJust());
- }
- // scriptName can be empty in special conditions e.g. eval
- auto scriptName = frame->GetScriptNameOrSourceURL();
- if (scriptName.IsEmpty()) {
- scriptName = v8_str("<unknown>");
- }
- CHECK(
- frame_obj->Set(context, v8_str("scriptName"), scriptName).FromJust());
- CHECK(frame_obj
- ->Set(context, v8_str("isEval"),
- v8::Boolean::New(isolate, frame->IsEval()))
- .FromJust());
- CHECK(frame_obj
- ->Set(context, v8_str("isConstructor"),
- v8::Boolean::New(isolate, frame->IsConstructor()))
- .FromJust());
- CHECK(frame_obj
- ->Set(context, v8_str("isWasm"),
- v8::Boolean::New(isolate, frame->IsWasm()))
- .FromJust());
- }
- } else {
- // No stack trace. We only have one stack frame of info..
- frames = v8::Array::New(isolate, 1);
-
- auto frame_obj = v8::Object::New(isolate);
- CHECK(frames->Set(context, 0, frame_obj).FromJust());
-
- auto line =
- v8::Integer::New(isolate, message->GetLineNumber(context).FromJust());
- auto column =
- v8::Integer::New(isolate, message->GetStartColumn(context).FromJust());
-
- CHECK(frame_obj->Set(context, v8_str("line"), line).FromJust());
- CHECK(frame_obj->Set(context, v8_str("column"), column).FromJust());
- CHECK(frame_obj
- ->Set(context, v8_str("scriptName"),
- message->GetScriptResourceName())
- .FromJust());
- }
-
- CHECK(json_obj->Set(context, v8_str("frames"), frames).FromJust());
- json_obj = handle_scope.Escape(json_obj);
- return json_obj;
-}
-
-std::string EncodeMessageAsJSON(v8::Local<v8::Context> context,
- v8::Local<v8::Message> message) {
- auto* isolate = context->GetIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context);
- auto json_obj = EncodeMessageAsObject(context, message);
- auto json_string = v8::JSON::Stringify(context, json_obj).ToLocalChecked();
- v8::String::Utf8Value json_string_(isolate, json_string);
- return std::string(ToCString(json_string_));
-}
-
-v8::Local<v8::Object> EncodeExceptionAsObject(v8::Local<v8::Context> context,
- v8::Local<v8::Value> exception) {
- auto* isolate = context->GetIsolate();
- v8::EscapableHandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context);
-
- auto message = v8::Exception::CreateMessage(isolate, exception);
- auto json_obj = EncodeMessageAsObject(context, message);
- json_obj = handle_scope.Escape(json_obj);
- return json_obj;
-}
-
-std::string EncodeExceptionAsJSON(v8::Local<v8::Context> context,
- v8::Local<v8::Value> exception) {
- auto* isolate = context->GetIsolate();
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context);
-
- auto message = v8::Exception::CreateMessage(isolate, exception);
- return EncodeMessageAsJSON(context, message);
-}
-
-void HandleException(v8::Local<v8::Context> context,
- v8::Local<v8::Value> exception) {
- v8::Isolate* isolate = context->GetIsolate();
-
- // TerminateExecution was called
- if (isolate->IsExecutionTerminating()) {
- // cancel exception termination so that the exception can be created
- isolate->CancelTerminateExecution();
-
- // maybe make a new exception object
- if (exception->IsNullOrUndefined()) {
- exception = v8::Exception::Error(v8_str("execution terminated"));
- }
-
- // handle the exception as if it is a regular exception
- HandleException(context, exception);
-
- // re-enable exception termination
- isolate->TerminateExecution();
- return;
- }
-
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- std::string json_str = EncodeExceptionAsJSON(context, exception);
- CHECK_NOT_NULL(d);
- d->last_exception_ = json_str;
- d->last_exception_handle_.Reset(isolate, exception);
-}
-
-void HandleExceptionMessage(v8::Local<v8::Context> context,
- v8::Local<v8::Message> message) {
- v8::Isolate* isolate = context->GetIsolate();
-
- // TerminateExecution was called
- if (isolate->IsExecutionTerminating()) {
- HandleException(context, v8::Undefined(isolate));
- return;
- }
-
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- std::string json_str = EncodeMessageAsJSON(context, message);
- CHECK_NOT_NULL(d);
- d->last_exception_ = json_str;
-}
-
-void ClearException(v8::Local<v8::Context> context) {
- v8::Isolate* isolate = context->GetIsolate();
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
- CHECK_NOT_NULL(d);
-
- d->last_exception_.clear();
- d->last_exception_handle_.Reset();
-}
-
-void ThrowInvalidArgument(v8::Isolate* isolate) {
- isolate->ThrowException(v8::Exception::TypeError(v8_str("Invalid Argument")));
-}
-
-} // namespace deno
diff --git a/core/libdeno/exceptions.h b/core/libdeno/exceptions.h
deleted file mode 100644
index 155dc8aad..000000000
--- a/core/libdeno/exceptions.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#ifndef EXCEPTIONS_H_
-#define EXCEPTIONS_H_
-
-#include <string>
-#include "v8/include/v8.h"
-
-namespace deno {
-
-v8::Local<v8::Object> EncodeExceptionAsObject(v8::Local<v8::Context> context,
- v8::Local<v8::Value> exception);
-
-std::string EncodeExceptionAsJSON(v8::Local<v8::Context> context,
- v8::Local<v8::Value> exception);
-
-void HandleException(v8::Local<v8::Context> context,
- v8::Local<v8::Value> exception);
-
-void HandleExceptionMessage(v8::Local<v8::Context> context,
- v8::Local<v8::Message> message);
-
-void ClearException(v8::Local<v8::Context> context);
-
-void ThrowInvalidArgument(v8::Isolate* isolate);
-} // namespace deno
-
-#endif // EXCEPTIONS_H_
diff --git a/core/libdeno/internal.h b/core/libdeno/internal.h
deleted file mode 100644
index 9669473a1..000000000
--- a/core/libdeno/internal.h
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#ifndef INTERNAL_H_
-#define INTERNAL_H_
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "buffer.h"
-#include "deno.h"
-#include "v8/include/v8.h"
-#include "v8/src/base/logging.h"
-
-namespace deno {
-
-struct ModuleInfo {
- bool main;
- std::string name;
- v8::Persistent<v8::Module> handle;
- std::vector<std::string> import_specifiers;
-
- ModuleInfo(v8::Isolate* isolate, v8::Local<v8::Module> module, bool main_,
- const char* name_, std::vector<std::string> import_specifiers_)
- : main(main_), name(name_), import_specifiers(import_specifiers_) {
- handle.Reset(isolate, module);
- }
-};
-
-// deno_s = Wrapped Isolate.
-class DenoIsolate {
- public:
- explicit DenoIsolate(deno_config config)
- : isolate_(nullptr),
- locker_(nullptr),
- shared_(config.shared),
- current_args_(nullptr),
- snapshot_creator_(nullptr),
- global_import_buf_ptr_(nullptr),
- recv_cb_(config.recv_cb),
- user_data_(nullptr),
- resolve_cb_(nullptr),
- next_dyn_import_id_(0),
- dyn_import_cb_(config.dyn_import_cb),
- has_snapshotted_(false) {
- if (config.load_snapshot.data_ptr) {
- snapshot_.data =
- reinterpret_cast<const char*>(config.load_snapshot.data_ptr);
- snapshot_.raw_size = static_cast<int>(config.load_snapshot.data_len);
- }
- }
-
- ~DenoIsolate() {
- last_exception_handle_.Reset();
- shared_ab_.Reset();
- if (locker_) {
- delete locker_;
- }
- if (snapshot_creator_) {
- // TODO(ry) V8 has a strange assert which prevents a SnapshotCreator from
- // being deallocated if it hasn't created a snapshot yet.
- // https://github.com/v8/v8/blob/73212783fbd534fac76cc4b66aac899c13f71fc8/src/api.cc#L603
- // If that assert is removed, this if guard could be removed.
- // WARNING: There may be false positive LSAN errors here.
- if (has_snapshotted_) {
- delete snapshot_creator_;
- }
- } else {
- isolate_->Dispose();
- }
- }
-
- static inline DenoIsolate* FromIsolate(v8::Isolate* isolate) {
- return static_cast<DenoIsolate*>(isolate->GetData(0));
- }
-
- void AddIsolate(v8::Isolate* isolate);
-
- deno_mod RegisterModule(bool main, const char* name, const char* source);
- void ClearModules();
-
- ModuleInfo* GetModuleInfo(deno_mod id) {
- if (id == 0) {
- return nullptr;
- }
- auto it = mods_.find(id);
- if (it != mods_.end()) {
- return &it->second;
- } else {
- return nullptr;
- }
- }
-
- v8::Isolate* isolate_;
- v8::Locker* locker_;
- deno_buf shared_;
- const v8::FunctionCallbackInfo<v8::Value>* current_args_;
- v8::SnapshotCreator* snapshot_creator_;
- void* global_import_buf_ptr_;
- deno_recv_cb recv_cb_;
- void* user_data_;
-
- std::map<deno_mod, ModuleInfo> mods_;
- std::map<std::string, deno_mod> mods_by_name_;
- deno_resolve_cb resolve_cb_;
-
- deno_dyn_import_id next_dyn_import_id_;
- deno_dyn_import_cb dyn_import_cb_;
- std::map<deno_dyn_import_id, v8::Persistent<v8::Promise::Resolver>>
- dyn_import_map_;
-
- v8::Persistent<v8::Context> context_;
- std::map<int, v8::Persistent<v8::Value>> pending_promise_map_;
- std::string last_exception_;
- v8::Persistent<v8::Value> last_exception_handle_;
- v8::Persistent<v8::Function> recv_;
- v8::StartupData snapshot_;
- v8::Persistent<v8::ArrayBuffer> global_import_buf_;
- v8::Persistent<v8::SharedArrayBuffer> shared_ab_;
- bool has_snapshotted_;
-};
-
-class UserDataScope {
- DenoIsolate* deno_;
- void* prev_data_;
- void* data_; // Not necessary; only for sanity checking.
-
- public:
- UserDataScope(DenoIsolate* 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_;
- }
-};
-
-struct InternalFieldData {
- uint32_t data;
-};
-
-static inline v8::Local<v8::String> v8_str(const char* x) {
- return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x,
- v8::NewStringType::kNormal)
- .ToLocalChecked();
-}
-
-static inline DenoIsolate* unwrap(Deno* d_) {
- return reinterpret_cast<deno::DenoIsolate*>(d_);
-}
-
-const char* ToCString(const v8::String::Utf8Value& value);
-
-void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
-void Recv(const v8::FunctionCallbackInfo<v8::Value>& args);
-void Send(const v8::FunctionCallbackInfo<v8::Value>& args);
-void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args);
-void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args);
-void Shared(v8::Local<v8::Name> property,
- const v8::PropertyCallbackInfo<v8::Value>& info);
-void MessageCallback(v8::Local<v8::Message> message, v8::Local<v8::Value> data);
-void QueueMicrotask(const v8::FunctionCallbackInfo<v8::Value>& args);
-static intptr_t external_references[] = {
- reinterpret_cast<intptr_t>(Print),
- reinterpret_cast<intptr_t>(Recv),
- reinterpret_cast<intptr_t>(Send),
- reinterpret_cast<intptr_t>(EvalContext),
- reinterpret_cast<intptr_t>(ErrorToJSON),
- reinterpret_cast<intptr_t>(Shared),
- reinterpret_cast<intptr_t>(MessageCallback),
- reinterpret_cast<intptr_t>(QueueMicrotask),
- 0};
-
-static const deno_buf empty_buf = {nullptr, 0};
-static const deno_snapshot empty_snapshot = {nullptr, 0};
-
-Deno* NewFromSnapshot(void* user_data, deno_recv_cb cb);
-
-void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context);
-
-void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
- v8::StartupData payload, void* data);
-
-v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index,
- void* data);
-
-v8::Local<v8::Uint8Array> ImportBuf(DenoIsolate* d, deno_buf buf);
-
-bool Execute(v8::Local<v8::Context> context, const char* js_filename,
- const char* js_source);
-bool ExecuteMod(v8::Local<v8::Context> context, const char* js_filename,
- const char* js_source, bool resolve_only);
-
-} // namespace deno
-
-extern "C" {
-// This is just to workaround the linker.
-struct deno_s {
- deno::DenoIsolate isolate;
-};
-}
-
-#endif // INTERNAL_H_
diff --git a/core/libdeno/libdeno_test.cc b/core/libdeno/libdeno_test.cc
deleted file mode 100644
index 1b21eb7b1..000000000
--- a/core/libdeno/libdeno_test.cc
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include "test.h"
-
-TEST(LibDenoTest, InitializesCorrectly) {
- EXPECT_NE(snapshot.data_ptr, nullptr);
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "1 + 2");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, Snapshotter) {
- Deno* d1 = deno_new(deno_config{1, empty_snapshot, empty, nullptr, nullptr});
- deno_execute(d1, nullptr, "a.js", "a = 1 + 2");
- EXPECT_EQ(nullptr, deno_last_exception(d1));
- deno_snapshot test_snapshot = deno_snapshot_new(d1);
- deno_delete(d1);
-
- Deno* d2 = deno_new(deno_config{0, test_snapshot, empty, nullptr, nullptr});
- deno_execute(d2, nullptr, "b.js", "if (a != 3) throw Error('x');");
- EXPECT_EQ(nullptr, deno_last_exception(d2));
- deno_delete(d2);
-
- deno_snapshot_delete(test_snapshot);
-}
-
-TEST(LibDenoTest, CanCallFunction) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_lock(d);
- deno_execute(d, nullptr, "a.js",
- "if (CanCallFunction() != 'foo') throw Error();");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_unlock(d);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, ErrorsCorrectly) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "throw Error()");
- EXPECT_NE(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-void assert_null(deno_pinned_buf b) {
- EXPECT_EQ(b.data_ptr, nullptr);
- EXPECT_EQ(b.data_len, 0u);
- EXPECT_EQ(b.pin, nullptr);
-}
-
-TEST(LibDenoTest, RecvReturnEmpty) {
- static int count = 0;
- auto recv_cb = [](auto _, deno_op_id op_id, auto buf, auto zero_copy_buf) {
- EXPECT_EQ(op_id, 42u);
- assert_null(zero_copy_buf);
- count++;
- EXPECT_EQ(static_cast<size_t>(3), buf.data_len);
- EXPECT_EQ(buf.data_ptr[0], 'a');
- EXPECT_EQ(buf.data_ptr[1], 'b');
- EXPECT_EQ(buf.data_ptr[2], 'c');
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
- deno_execute(d, nullptr, "a.js", "RecvReturnEmpty()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(count, 2);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, BasicRecv) {
- static int count = 0;
- auto recv_cb = [](auto user_data, deno_op_id op_id, auto buf,
- auto zero_copy_buf) {
- EXPECT_EQ(op_id, 42u);
- // auto d = reinterpret_cast<Deno*>(user_data);
- assert_null(zero_copy_buf);
- count++;
- EXPECT_EQ(static_cast<size_t>(3), buf.data_len);
- EXPECT_EQ(buf.data_ptr[0], 1);
- EXPECT_EQ(buf.data_ptr[1], 2);
- EXPECT_EQ(buf.data_ptr[2], 3);
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
- deno_execute(d, d, "a.js", "BasicRecv()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(count, 1);
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
- {
- deno_lock(d);
- uint8_t response[] = {'b', 'a', 'r'};
- deno_respond(d, nullptr, 43, {response, sizeof response});
- deno_unlock(d);
- }
- EXPECT_EQ(count, 2);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, RecvReturnBar) {
- static int count = 0;
- auto recv_cb = [](auto user_data, deno_op_id op_id, auto buf,
- auto zero_copy_buf) {
- EXPECT_EQ(op_id, 42u);
- auto d = reinterpret_cast<Deno*>(user_data);
- assert_null(zero_copy_buf);
- count++;
- EXPECT_EQ(static_cast<size_t>(3), buf.data_len);
- EXPECT_EQ(buf.data_ptr[0], 'a');
- EXPECT_EQ(buf.data_ptr[1], 'b');
- EXPECT_EQ(buf.data_ptr[2], 'c');
- uint8_t response[] = {'b', 'a', 'r'};
- deno_respond(d, user_data, op_id, {response, sizeof response});
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
- deno_execute(d, d, "a.js", "RecvReturnBar()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(count, 1);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, DoubleRecvFails) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "DoubleRecvFails()");
- EXPECT_NE(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, TypedArraySnapshots) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "TypedArraySnapshots()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, SnapshotBug) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "SnapshotBug()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, GlobalErrorHandling) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "GlobalErrorHandling()");
- std::string expected =
- "{\"message\":\"Uncaught ReferenceError: notdefined is not defined\","
- "\"sourceLine\":\" "
- "notdefined()\",\"scriptResourceName\":\"helloworld.js\","
- "\"lineNumber\":3,\"startPosition\":3,\"endPosition\":4,\"errorLevel\":8,"
- "\"startColumn\":1,\"endColumn\":2,\"isSharedCrossOrigin\":false,"
- "\"isOpaque\":false,\"frames\":[{\"line\":3,\"column\":2,"
- "\"functionName\":\"eval\",\"scriptName\":\"helloworld.js\",\"isEval\":"
- "true,"
- "\"isConstructor\":false,\"isWasm\":false},";
- std::string actual(deno_last_exception(d), 0, expected.length());
- EXPECT_STREQ(expected.c_str(), actual.c_str());
- deno_delete(d);
-}
-
-TEST(LibDenoTest, ZeroCopyBuf) {
- static int count = 0;
- static deno_pinned_buf zero_copy_buf2;
- auto recv_cb = [](auto user_data, deno_op_id op_id, deno_buf buf,
- deno_pinned_buf zero_copy_buf) {
- EXPECT_EQ(op_id, 42u);
- count++;
- EXPECT_NE(zero_copy_buf.pin, nullptr);
- zero_copy_buf.data_ptr[0] = 4;
- zero_copy_buf.data_ptr[1] = 2;
- zero_copy_buf2 = zero_copy_buf;
- EXPECT_EQ(2u, buf.data_len);
- EXPECT_EQ(2u, zero_copy_buf.data_len);
- EXPECT_EQ(buf.data_ptr[0], 1);
- EXPECT_EQ(buf.data_ptr[1], 2);
- // Note zero_copy_buf won't actually be freed here because in
- // libdeno_test.js zeroCopyBuf is a rooted global. We just want to exercise
- // the API here.
- deno_pinned_buf_delete(&zero_copy_buf);
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
- deno_execute(d, d, "a.js", "ZeroCopyBuf()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(count, 1);
- // zero_copy_buf was subsequently changed in JS, let's check that our copy
- // reflects that.
- EXPECT_EQ(zero_copy_buf2.data_ptr[0], 9);
- EXPECT_EQ(zero_copy_buf2.data_ptr[1], 8);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, CheckPromiseErrors) {
- static int count = 0;
- auto recv_cb = [](auto _, deno_op_id op_id, auto buf, auto zero_copy_buf) {
- count++;
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_execute(d, nullptr, "a.js", "CheckPromiseErrors()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(count, 1);
- // We caught the exception. So still no errors after calling
- // deno_check_promise_errors().
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, LastException) {
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, nullptr, nullptr});
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_execute(d, nullptr, "a.js", "\n\nthrow Error('boo');\n\n");
- EXPECT_STREQ(deno_last_exception(d),
- "{\"message\":\"Uncaught Error: boo\",\"sourceLine\":\"throw "
- "Error('boo');\",\"scriptResourceName\":\"a.js\",\"lineNumber\":"
- "3,\"startPosition\":8,\"endPosition\":9,\"errorLevel\":8,"
- "\"startColumn\":6,\"endColumn\":7,\"isSharedCrossOrigin\":"
- "false,\"isOpaque\":false,\"frames\":[{\"line\":3,\"column\":7,"
- "\"scriptName\":\"a.js\",\"isEval\":false,"
- "\"isConstructor\":false,\"isWasm\":false}]}");
- deno_delete(d);
-}
-
-TEST(LibDenoTest, EncodeErrorBug) {
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, nullptr, nullptr});
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_execute(d, nullptr, "a.js", "eval('a')");
- EXPECT_STREQ(
- deno_last_exception(d),
- "{\"message\":\"Uncaught ReferenceError: a is not "
- "defined\",\"sourceLine\":\"a\",\"lineNumber\":1,\"startPosition\":0,"
- "\"endPosition\":1,\"errorLevel\":8,\"startColumn\":0,\"endColumn\":1,"
- "\"isSharedCrossOrigin\":false,\"isOpaque\":false,\"frames\":[{\"line\":"
- "1,\"column\":1,\"functionName\":\"eval\",\"scriptName\":\"<unknown>\","
- "\"isEval\":true,\"isConstructor\":false,\"isWasm\":false},{\"line\":1,"
- "\"column\":1,\"scriptName\":\"a.js\",\"isEval\":"
- "false,\"isConstructor\":false,\"isWasm\":false}]}");
- deno_delete(d);
-}
-
-TEST(LibDenoTest, Shared) {
- uint8_t s[] = {0, 1, 2};
- deno_buf shared = {s, sizeof s};
- Deno* d = deno_new(deno_config{0, snapshot, shared, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "Shared()");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(s[0], 42);
- EXPECT_EQ(s[1], 43);
- EXPECT_EQ(s[2], 44);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, Utf8Bug) {
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, nullptr, nullptr});
- // The following is a valid UTF-8 javascript which just defines a string
- // literal. We had a bug where libdeno would choke on this.
- deno_execute(d, nullptr, "a.js", "x = \"\xEF\xBF\xBD\"");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, LibDenoEvalContext) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "LibDenoEvalContext();");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, LibDenoEvalContextError) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "LibDenoEvalContextError();");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, LibDenoEvalContextInvalidArgument) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "LibDenoEvalContextInvalidArgument();");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, LibDenoPrintInvalidArgument) {
- Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js", "LibDenoPrintInvalidArgument();");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_delete(d);
-}
-
-TEST(LibDenoTest, SharedAtomics) {
- int32_t s[] = {0, 1, 2};
- deno_buf shared = {reinterpret_cast<uint8_t*>(s), sizeof s};
- Deno* d = deno_new(deno_config{0, empty_snapshot, shared, nullptr, nullptr});
- deno_execute(d, nullptr, "a.js",
- "Atomics.add(new Int32Array(Deno.core.shared), 0, 1)");
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(s[0], 1);
- EXPECT_EQ(s[1], 1);
- EXPECT_EQ(s[2], 2);
- deno_delete(d);
-}
-
-TEST(LibDenoTest, WasmInstantiate) {
- static int count = 0;
- auto recv_cb = [](auto _, deno_op_id op_id, auto buf, auto zero_copy_buf) {
- EXPECT_EQ(op_id, 42u);
- EXPECT_EQ(buf.data_len, 1u);
- EXPECT_EQ(buf.data_ptr[0], 42);
- count++;
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, nullptr});
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_execute(d, nullptr, "a.js", "WasmInstantiate()");
-
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- EXPECT_EQ(count, 3);
-
- deno_delete(d);
-}
diff --git a/core/libdeno/libdeno_test.js b/core/libdeno/libdeno_test.js
deleted file mode 100644
index 5477a87a0..000000000
--- a/core/libdeno/libdeno_test.js
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-
-// A simple runtime that doesn't involve typescript or protobufs to test
-// libdeno. Invoked by libdeno_test.cc
-
-// eslint-disable-next-line @typescript-eslint/no-this-alias
-const global = this;
-
-function assert(cond) {
- if (!cond) throw Error("libdeno_test.js assert failed");
-}
-
-global.CanCallFunction = () => {
- Deno.core.print("Hello world from foo");
- return "foo";
-};
-
-// This object is created to test snapshotting.
-// See DeserializeInternalFieldsCallback and SerializeInternalFieldsCallback.
-const snapshotted = new Uint8Array([1, 3, 3, 7]);
-
-global.TypedArraySnapshots = () => {
- assert(snapshotted[0] === 1);
- assert(snapshotted[1] === 3);
- assert(snapshotted[2] === 3);
- assert(snapshotted[3] === 7);
-};
-
-global.RecvReturnEmpty = () => {
- const m1 = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
- const m2 = m1.slice();
- const r1 = Deno.core.send(42, m1);
- assert(r1 == null);
- const r2 = Deno.core.send(42, m2);
- assert(r2 == null);
-};
-
-global.BasicRecv = () => {
- const m = new Uint8Array([1, 2, 3]);
- Deno.core.recv((opId, buf) => {
- assert(opId === 43);
- assert(buf instanceof Uint8Array);
- assert(buf.byteLength === 3);
- const s = String.fromCharCode(...buf);
- assert(s === "bar");
- const r = Deno.core.send(42, m);
- assert(!r); // async
- });
- const r = Deno.core.send(42, m);
- assert(!r); // async
-};
-
-global.RecvReturnBar = () => {
- const m = new Uint8Array("abc".split("").map(c => c.charCodeAt(0)));
- const r = Deno.core.send(42, m);
- assert(r instanceof Uint8Array);
- assert(r.byteLength === 3);
- const rstr = String.fromCharCode(...r);
- assert(rstr === "bar");
-};
-
-global.DoubleRecvFails = () => {
- // Deno.core.recv is an internal function and should only be called once from the
- // runtime.
- Deno.core.recv((_channel, _msg) => assert(false));
- Deno.core.recv((_channel, _msg) => assert(false));
-};
-
-global.SendRecvSlice = () => {
- const abLen = 1024;
- let buf = new Uint8Array(abLen);
- for (let i = 0; i < 5; i++) {
- // Set first and last byte, for verification by the native side.
- buf[0] = 100 + i;
- buf[buf.length - 1] = 100 - i;
- // On the native side, the slice is shortened by 19 bytes.
- buf = Deno.core.send(42, buf);
- assert(buf.byteOffset === i * 11);
- assert(buf.byteLength === abLen - i * 30 - 19);
- assert(buf.buffer.byteLength == abLen);
- // Look for values written by the backend.
- assert(buf[0] === 200 + i);
- assert(buf[buf.length - 1] === 200 - i);
- // On the JS side, the start of the slice is moved up by 11 bytes.
- buf = buf.subarray(11);
- assert(buf.byteOffset === (i + 1) * 11);
- assert(buf.byteLength === abLen - (i + 1) * 30);
- }
-};
-
-global.JSSendArrayBufferViewTypes = () => {
- // Test that ArrayBufferView slices are transferred correctly.
- // Send Uint8Array.
- const ab1 = new ArrayBuffer(4321);
- const u8 = new Uint8Array(ab1, 2468, 1000);
- u8[0] = 1;
- Deno.core.send(42, u8);
- // Send Uint32Array.
- const ab2 = new ArrayBuffer(4321);
- const u32 = new Uint32Array(ab2, 2468, 1000 / Uint32Array.BYTES_PER_ELEMENT);
- u32[0] = 0x02020202;
- Deno.core.send(42, u32);
- // Send DataView.
- const ab3 = new ArrayBuffer(4321);
- const dv = new DataView(ab3, 2468, 1000);
- dv.setUint8(0, 3);
- Deno.core.send(42, dv);
-};
-
-// The following join has caused SnapshotBug to segfault when using kKeep.
-[].join("");
-
-global.SnapshotBug = () => {
- assert("1,2,3" === String([1, 2, 3]));
-};
-
-global.GlobalErrorHandling = () => {
- eval("\n\n notdefined()\n//# sourceURL=helloworld.js");
-};
-
-// Allocate this buf at the top level to avoid GC.
-const zeroCopyBuf = new Uint8Array([3, 4]);
-
-global.ZeroCopyBuf = () => {
- const a = new Uint8Array([1, 2]);
- const b = zeroCopyBuf;
- // The second parameter of send should modified by the
- // privileged side.
- const r = Deno.core.send(42, a, b);
- assert(r == null);
- // b is different.
- assert(b[0] === 4);
- assert(b[1] === 2);
- // Now we modify it again.
- b[0] = 9;
- b[1] = 8;
-};
-
-global.CheckPromiseErrors = () => {
- async function fn() {
- throw new Error("message");
- }
-
- (async () => {
- try {
- await fn();
- } catch (e) {
- Deno.core.send(42, new Uint8Array([42]));
- }
- })();
-};
-
-global.Shared = () => {
- const ab = Deno.core.shared;
- assert(ab instanceof SharedArrayBuffer);
- assert(Deno.core.shared != undefined);
- assert(ab.byteLength === 3);
- const ui8 = new Uint8Array(ab);
- assert(ui8[0] === 0);
- assert(ui8[1] === 1);
- assert(ui8[2] === 2);
- ui8[0] = 42;
- ui8[1] = 43;
- ui8[2] = 44;
-};
-
-global.LibDenoEvalContext = () => {
- const [result, errInfo] = Deno.core.evalContext("let a = 1; a");
- assert(result === 1);
- assert(!errInfo);
- const [result2, errInfo2] = Deno.core.evalContext("a = a + 1; a");
- assert(result2 === 2);
- assert(!errInfo2);
-};
-
-global.LibDenoEvalContextError = () => {
- const [result, errInfo] = Deno.core.evalContext("not_a_variable");
- assert(!result);
- assert(!!errInfo);
- assert(errInfo.isNativeError); // is a native error (ReferenceError)
- assert(!errInfo.isCompileError); // is NOT a compilation error
- assert(errInfo.thrown.message === "not_a_variable is not defined");
-
- const [result2, errInfo2] = Deno.core.evalContext("throw 1");
- assert(!result2);
- assert(!!errInfo2);
- assert(!errInfo2.isNativeError); // is NOT a native error
- assert(!errInfo2.isCompileError); // is NOT a compilation error
- assert(errInfo2.thrown === 1);
-
- const [result3, errInfo3] = Deno.core.evalContext(
- "class AError extends Error {}; throw new AError('e')"
- );
- assert(!result3);
- assert(!!errInfo3);
- assert(errInfo3.isNativeError); // extend from native error, still native error
- assert(!errInfo3.isCompileError); // is NOT a compilation error
- assert(errInfo3.thrown.message === "e");
-
- const [result4, errInfo4] = Deno.core.evalContext("{");
- assert(!result4);
- assert(!!errInfo4);
- assert(errInfo4.isNativeError); // is a native error (SyntaxError)
- assert(errInfo4.isCompileError); // is a compilation error! (braces not closed)
- assert(errInfo4.thrown.message === "Unexpected end of input");
-
- const [result5, errInfo5] = Deno.core.evalContext("eval('{')");
- assert(!result5);
- assert(!!errInfo5);
- assert(errInfo5.isNativeError); // is a native error (SyntaxError)
- assert(!errInfo5.isCompileError); // is NOT a compilation error! (just eval)
- assert(errInfo5.thrown.message === "Unexpected end of input");
-};
-
-global.LibDenoEvalContextInvalidArgument = () => {
- try {
- Deno.core.evalContext();
- } catch (e) {
- assert(e instanceof TypeError);
- assert(e.message === "Invalid Argument");
- }
-};
-
-global.LibDenoPrintInvalidArgument = () => {
- try {
- Deno.core.print();
- } catch (e) {
- assert(e instanceof TypeError);
- assert(e.message === "Invalid Argument");
- }
- try {
- Deno.core.print(2, 3, 4);
- } catch (e) {
- assert(e instanceof TypeError);
- assert(e.message === "Invalid Argument");
- }
-};
-
-global.WasmInstantiate = () => {
- // The following blob can be created by taking the following s-expr and pass
- // it through wat2wasm.
- // (module
- // (func $add (param $a i32) (param $b i32) (result i32)
- // local.get $a
- // local.get $b
- // i32.add)
- // (export "add" (func $add))
- // )
- // prettier-ignore
- const bytes = new Uint8Array([
- 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60,
- 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01,
- 0x03, 0x61, 0x64, 0x64, 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20,
- 0x00, 0x20, 0x01, 0x6a, 0x0b
- ]);
-
- (async () => {
- Deno.core.send(42, new Uint8Array([42]));
-
- const wasm = await WebAssembly.instantiate(bytes);
-
- Deno.core.send(42, new Uint8Array([42]));
-
- const result = wasm.instance.exports.add(1, 3);
- if (result != 4) {
- throw Error("bad");
- }
- // To signal success, we send back a fixed buffer.
- Deno.core.send(42, new Uint8Array([42]));
- })();
-};
diff --git a/core/libdeno/modules.cc b/core/libdeno/modules.cc
deleted file mode 100644
index 9ccdbcadb..000000000
--- a/core/libdeno/modules.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include "exceptions.h"
-#include "internal.h"
-
-using deno::ClearException;
-using deno::DenoIsolate;
-using deno::HandleException;
-using v8::Boolean;
-using v8::Context;
-using v8::EscapableHandleScope;
-using v8::HandleScope;
-using v8::Integer;
-using v8::Isolate;
-using v8::Local;
-using v8::Locker;
-using v8::Module;
-using v8::Object;
-using v8::ScriptCompiler;
-using v8::ScriptOrigin;
-using v8::String;
-using v8::Value;
-
-v8::MaybeLocal<v8::Module> ResolveCallback(Local<Context> context,
- Local<String> specifier,
- Local<Module> referrer) {
- auto* isolate = context->GetIsolate();
- v8::Isolate::Scope isolate_scope(isolate);
- v8::Locker locker(isolate);
-
- DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
-
- v8::EscapableHandleScope handle_scope(isolate);
-
- deno_mod referrer_id = referrer->GetIdentityHash();
- auto* referrer_info = d->GetModuleInfo(referrer_id);
- CHECK_NOT_NULL(referrer_info);
-
- for (int i = 0; i < referrer->GetModuleRequestsLength(); i++) {
- Local<String> req = referrer->GetModuleRequest(i);
-
- if (req->Equals(context, specifier).ToChecked()) {
- v8::String::Utf8Value req_utf8(isolate, req);
- std::string req_str(*req_utf8);
-
- deno_mod id = d->resolve_cb_(d->user_data_, req_str.c_str(), referrer_id);
-
- // Note: id might be zero, in which case GetModuleInfo will return
- // nullptr.
- auto* info = d->GetModuleInfo(id);
- if (info == nullptr) {
- char buf[64 * 1024];
- snprintf(buf, sizeof(buf), "Cannot resolve module \"%s\" from \"%s\"",
- req_str.c_str(), referrer_info->name.c_str());
- isolate->ThrowException(deno::v8_str(buf));
- break;
- } else {
- Local<Module> child_mod = info->handle.Get(isolate);
- return handle_scope.Escape(child_mod);
- }
- }
- }
-
- return v8::MaybeLocal<v8::Module>(); // Error
-}
-
-extern "C" {
-
-deno_mod deno_mod_new(Deno* d_, bool main, const char* name_cstr,
- const char* source_cstr) {
- auto* d = deno::unwrap(d_);
- return d->RegisterModule(main, name_cstr, source_cstr);
-}
-
-const char* deno_mod_name(Deno* d_, deno_mod id) {
- auto* d = deno::unwrap(d_);
- auto* info = d->GetModuleInfo(id);
- return info->name.c_str();
-}
-
-size_t deno_mod_imports_len(Deno* d_, deno_mod id) {
- auto* d = deno::unwrap(d_);
- auto* info = d->GetModuleInfo(id);
- return info->import_specifiers.size();
-}
-
-const char* deno_mod_imports_get(Deno* d_, deno_mod id, size_t index) {
- auto* d = deno::unwrap(d_);
- auto* info = d->GetModuleInfo(id);
- if (info == nullptr || index >= info->import_specifiers.size()) {
- return nullptr;
- } else {
- return info->import_specifiers[index].c_str();
- }
-}
-
-void deno_mod_instantiate(Deno* d_, void* user_data, deno_mod id,
- deno_resolve_cb cb) {
- auto* d = deno::unwrap(d_);
- deno::UserDataScope user_data_scope(d, user_data);
-
- auto* isolate = d->isolate_;
- v8::Isolate::Scope isolate_scope(isolate);
- v8::Locker locker(isolate);
- v8::HandleScope handle_scope(isolate);
- auto context = d->context_.Get(d->isolate_);
- v8::Context::Scope context_scope(context);
-
- v8::TryCatch try_catch(isolate);
- {
- CHECK_NULL(d->resolve_cb_);
- d->resolve_cb_ = cb;
- {
- auto* info = d->GetModuleInfo(id);
- if (info == nullptr) {
- return;
- }
- Local<Module> module = info->handle.Get(isolate);
- if (module->GetStatus() == Module::kErrored) {
- return;
- }
- auto maybe_ok = module->InstantiateModule(context, ResolveCallback);
- CHECK(maybe_ok.IsJust() || try_catch.HasCaught());
- }
- d->resolve_cb_ = nullptr;
- }
-
- if (try_catch.HasCaught()) {
- HandleException(context, try_catch.Exception());
- }
-}
-
-void deno_mod_evaluate(Deno* d_, void* user_data, deno_mod id) {
- auto* d = deno::unwrap(d_);
- deno::UserDataScope user_data_scope(d, user_data);
-
- auto* isolate = d->isolate_;
- v8::Isolate::Scope isolate_scope(isolate);
- v8::Locker locker(isolate);
- v8::HandleScope handle_scope(isolate);
- auto context = d->context_.Get(d->isolate_);
- v8::Context::Scope context_scope(context);
-
- auto* info = d->GetModuleInfo(id);
- auto module = info->handle.Get(isolate);
- auto status = module->GetStatus();
-
- if (status == Module::kInstantiated) {
- bool ok = !module->Evaluate(context).IsEmpty();
- status = module->GetStatus(); // Update status after evaluating.
- if (ok) {
- // Note status can still be kErrored even if we get ok.
- CHECK(status == Module::kEvaluated || status == Module::kErrored);
- } else {
- CHECK_EQ(status, Module::kErrored);
- }
- }
-
- switch (status) {
- case Module::kEvaluated:
- ClearException(context);
- break;
- case Module::kErrored:
- HandleException(context, module->GetException());
- break;
- default:
- FATAL("Unexpected module status: %d", static_cast<int>(status));
- }
-}
-
-void deno_dyn_import_done(Deno* d_, void* user_data,
- deno_dyn_import_id import_id, deno_mod mod_id,
- const char* error_str) {
- auto* d = deno::unwrap(d_);
- CHECK((mod_id == 0 && error_str != nullptr) ||
- (mod_id != 0 && error_str == nullptr) ||
- (mod_id == 0 && !d->last_exception_handle_.IsEmpty()));
- deno::UserDataScope user_data_scope(d, user_data);
-
- auto* isolate = d->isolate_;
- v8::Isolate::Scope isolate_scope(isolate);
- v8::Locker locker(isolate);
- v8::HandleScope handle_scope(isolate);
- auto context = d->context_.Get(d->isolate_);
- v8::Context::Scope context_scope(context);
-
- auto it = d->dyn_import_map_.find(import_id);
- if (it == d->dyn_import_map_.end()) {
- CHECK(false); // TODO(ry) error on bad import_id.
- return;
- }
-
- /// Resolve.
- auto persistent_promise = &it->second;
- auto promise = persistent_promise->Get(isolate);
-
- auto* info = d->GetModuleInfo(mod_id);
-
- // Do the following callback into JS?? Is user_data_scope needed?
- persistent_promise->Reset();
- d->dyn_import_map_.erase(it);
-
- if (info == nullptr) {
- // Resolution error.
- if (error_str != nullptr) {
- auto msg = deno::v8_str(error_str);
- auto exception = v8::Exception::TypeError(msg);
- promise->Reject(context, exception).ToChecked();
- } else {
- auto e = d->last_exception_handle_.Get(isolate);
- ClearException(context);
- promise->Reject(context, e).ToChecked();
- }
- } else {
- // Resolution success
- Local<Module> module = info->handle.Get(isolate);
- CHECK_EQ(module->GetStatus(), v8::Module::kEvaluated);
- Local<Value> module_namespace = module->GetModuleNamespace();
- promise->Resolve(context, module_namespace).ToChecked();
- }
- d->isolate_->RunMicrotasks();
-}
-
-} // extern "C"
diff --git a/core/libdeno/modules_test.cc b/core/libdeno/modules_test.cc
deleted file mode 100644
index ee6a93112..000000000
--- a/core/libdeno/modules_test.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include "test.h"
-
-static int exec_count = 0;
-void recv_cb(void* user_data, deno_op_id op_id, deno_buf buf,
- deno_pinned_buf zero_copy_buf) {
- // We use this to check that scripts have executed.
- EXPECT_EQ(1u, buf.data_len);
- EXPECT_EQ(42u, op_id);
- EXPECT_EQ(buf.data_ptr[0], 4);
- EXPECT_EQ(zero_copy_buf.data_ptr, nullptr);
- EXPECT_EQ(zero_copy_buf.data_len, 0u);
- EXPECT_EQ(zero_copy_buf.pin, nullptr);
- exec_count++;
-}
-
-TEST(ModulesTest, Resolution) {
- exec_count = 0; // Reset
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, recv_cb, nullptr});
- EXPECT_EQ(0, exec_count);
-
- static deno_mod a = deno_mod_new(d, true, "a.js",
- "import { b } from 'b.js'\n"
- "if (b() != 'b') throw Error();\n"
- "Deno.core.send(42, new Uint8Array([4]));");
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- const char* b_src = "export function b() { return 'b' }";
- static deno_mod b = deno_mod_new(d, false, "b.js", b_src);
- EXPECT_NE(b, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- EXPECT_EQ(0, exec_count);
-
- EXPECT_EQ(1u, deno_mod_imports_len(d, a));
- EXPECT_EQ(0u, deno_mod_imports_len(d, b));
-
- EXPECT_STREQ("b.js", deno_mod_imports_get(d, a, 0));
- EXPECT_EQ(nullptr, deno_mod_imports_get(d, a, 1));
- EXPECT_EQ(nullptr, deno_mod_imports_get(d, b, 0));
-
- static int resolve_count = 0;
- auto resolve_cb = [](void* user_data, const char* specifier,
- deno_mod referrer) {
- EXPECT_EQ(referrer, a);
- EXPECT_STREQ(specifier, "b.js");
- resolve_count++;
- return b;
- };
-
- deno_mod_instantiate(d, d, b, resolve_cb);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(0, resolve_count);
- EXPECT_EQ(0, exec_count);
-
- deno_mod_instantiate(d, d, a, resolve_cb);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(1, resolve_count);
- EXPECT_EQ(0, exec_count);
-
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(1, resolve_count);
- EXPECT_EQ(1, exec_count);
-
- deno_delete(d);
-}
-
-TEST(ModulesTest, ResolutionError) {
- exec_count = 0; // Reset
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, recv_cb, nullptr});
- EXPECT_EQ(0, exec_count);
-
- static deno_mod a = deno_mod_new(d, true, "a.js",
- "import 'bad'\n"
- "Deno.core.send(42, new Uint8Array([4]));");
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- EXPECT_EQ(0, exec_count);
-
- EXPECT_EQ(1u, deno_mod_imports_len(d, a));
- EXPECT_STREQ("bad", deno_mod_imports_get(d, a, 0));
-
- static int resolve_count = 0;
- auto resolve_cb = [](void* user_data, const char* specifier,
- deno_mod referrer) {
- EXPECT_EQ(referrer, a);
- EXPECT_STREQ(specifier, "bad");
- resolve_count++;
- return 0;
- };
-
- deno_mod_instantiate(d, d, a, resolve_cb);
- EXPECT_NE(nullptr, deno_last_exception(d));
- EXPECT_EQ(1, resolve_count);
- EXPECT_EQ(0, exec_count);
-
- deno_delete(d);
-}
-
-TEST(ModulesTest, ImportMetaUrl) {
- exec_count = 0; // Reset
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, recv_cb, nullptr});
- EXPECT_EQ(0, exec_count);
-
- static deno_mod a =
- deno_mod_new(d, true, "a.js",
- "if ('a.js' != import.meta.url) throw 'hmm'\n"
- "Deno.core.send(42, new Uint8Array([4]));");
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- deno_mod_instantiate(d, d, a, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(0, exec_count);
-
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- EXPECT_EQ(1, exec_count);
-}
-
-TEST(ModulesTest, ImportMetaMain) {
- Deno* d = deno_new(deno_config{0, empty_snapshot, empty, recv_cb, nullptr});
-
- const char* throw_not_main_src = "if (!import.meta.main) throw 'err'";
- static deno_mod throw_not_main =
- deno_mod_new(d, true, "a.js", throw_not_main_src);
- EXPECT_NE(throw_not_main, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- deno_mod_instantiate(d, d, throw_not_main, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- deno_mod_evaluate(d, d, throw_not_main);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- const char* throw_main_src = "if (import.meta.main) throw 'err'";
- static deno_mod throw_main = deno_mod_new(d, false, "b.js", throw_main_src);
- EXPECT_NE(throw_main, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- deno_mod_instantiate(d, d, throw_main, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- deno_mod_evaluate(d, d, throw_main);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- deno_delete(d);
-}
-
-TEST(ModulesTest, DynamicImportSuccess) {
- exec_count = 0;
- static int dyn_import_count = 0;
- static deno_mod b = 0;
- auto dyn_import_cb = [](auto user_data, const char* specifier,
- const char* referrer, deno_dyn_import_id import_id) {
- auto d = reinterpret_cast<Deno*>(user_data);
- dyn_import_count++;
- EXPECT_STREQ(specifier, "foo");
- EXPECT_STREQ(referrer, "a.js");
- deno_dyn_import_done(d, d, import_id, b, nullptr);
- };
- const char* src =
- "(async () => { \n"
- " let mod = await import('foo'); \n"
- " assert(mod.b() === 'b'); \n"
- // Send a message to signify that we're done.
- " Deno.core.send(42, new Uint8Array([4])); \n"
- "})(); \n";
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
- static deno_mod a = deno_mod_new(d, true, "a.js", src);
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, a, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- const char* b_src = "export function b() { return 'b' }";
- b = deno_mod_new(d, false, "b.js", b_src);
- EXPECT_NE(b, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, b, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_evaluate(d, d, b);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
- deno_delete(d);
- EXPECT_EQ(1, exec_count);
- EXPECT_EQ(1, dyn_import_count);
-}
-
-TEST(ModulesTest, DynamicImportError) {
- exec_count = 0;
- static int dyn_import_count = 0;
- auto dyn_import_cb = [](auto user_data, const char* specifier,
- const char* referrer, deno_dyn_import_id import_id) {
- auto d = reinterpret_cast<Deno*>(user_data);
- dyn_import_count++;
- EXPECT_STREQ(specifier, "foo");
- EXPECT_STREQ(referrer, "a.js");
- // We indicate there was an error resolving by returning mod_id 0.
- deno_dyn_import_done(d, d, import_id, 0, "foo not found");
- };
- const char* src =
- "(async () => { \n"
- " let mod = await import('foo'); \n"
- // The following should be unreachable.
- " Deno.core.send(42, new Uint8Array([4])); \n"
- "})(); \n";
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
- static deno_mod a = deno_mod_new(d, true, "a.js", src);
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, a, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- // No error when evaluating, because it's an async error.
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- // Now we should get an error.
- deno_check_promise_errors(d);
- EXPECT_NE(deno_last_exception(d), nullptr);
- std::string e(deno_last_exception(d));
- EXPECT_NE(e.find("Uncaught TypeError: foo not found"), std::string::npos);
- deno_delete(d);
- EXPECT_EQ(0, exec_count);
- EXPECT_EQ(1, dyn_import_count);
-}
-
-TEST(ModulesTest, DynamicImportAsync) {
- exec_count = 0;
- static int dyn_import_count = 0;
- static deno_mod b = 0;
- static std::vector<deno_dyn_import_id> import_ids = {};
- auto dyn_import_cb = [](auto user_data, const char* specifier,
- const char* referrer, deno_dyn_import_id import_id) {
- // auto d = reinterpret_cast<Deno*>(user_data);
- dyn_import_count++;
- EXPECT_STREQ(specifier, "foo");
- EXPECT_STREQ(referrer, "a.js");
- // We don't call deno_dyn_import_done until later.
- import_ids.push_back(import_id);
- };
- const char* src =
- "(async () => { \n"
- " let mod = await import('foo'); \n"
- " assert(mod.b() === 'b'); \n"
- // AGAIN!
- " mod = await import('foo'); \n"
- " assert(mod.b() === 'b'); \n"
- // Send a message to signify that we're done.
- " Deno.core.send(42, new Uint8Array([4])); \n"
- "})(); \n";
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
- static deno_mod a = deno_mod_new(d, true, "a.js", src);
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, a, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- // Evaluate. We check that there are no errors, and Deno.core.send has not
- // been called.
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
- EXPECT_EQ(0, exec_count);
- EXPECT_EQ(1, dyn_import_count);
-
- // Instantiate b.js
- const char* b_src = "export function b() { return 'b' }";
- b = deno_mod_new(d, false, "b.js", b_src);
- EXPECT_NE(b, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, b, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_evaluate(d, d, b);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- // Now we resolve the import.
- EXPECT_EQ(1u, import_ids.size());
- auto import_id = import_ids.back();
- import_ids.pop_back();
-
- deno_dyn_import_done(d, d, import_id, b, nullptr);
-
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
-
- EXPECT_EQ(1u, import_ids.size());
- EXPECT_EQ(2, dyn_import_count);
- EXPECT_EQ(0, exec_count);
-
- import_id = import_ids.back();
- import_ids.pop_back();
- deno_dyn_import_done(d, d, import_id, b, nullptr);
-
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
-
- // We still have to resolve the second one
- EXPECT_EQ(2, dyn_import_count);
- EXPECT_EQ(1, exec_count);
-
- deno_delete(d);
-}
-
-TEST(ModulesTest, DynamicImportThrows) {
- exec_count = 0;
- static int dyn_import_count = 0;
- static deno_mod b = 0;
- static std::vector<deno_dyn_import_id> import_ids = {};
- auto dyn_import_cb = [](auto user_data, const char* specifier,
- const char* referrer, deno_dyn_import_id import_id) {
- dyn_import_count++;
- EXPECT_STREQ(specifier, "b.js");
- EXPECT_STREQ(referrer, "a.js");
- // We don't call deno_dyn_import_done until later.
- import_ids.push_back(import_id);
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
-
- // Instantiate and evaluate the root module. This should succeed.
- const char* a_src =
- "(async () => { \n"
- " let mod = await import('b.js'); \n"
- // unreachable
- " Deno.core.send(42, new Uint8Array([4])); \n"
- "})(); \n";
- static deno_mod a = deno_mod_new(d, true, "a.js", a_src);
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, a, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_check_promise_errors(d);
- EXPECT_EQ(deno_last_exception(d), nullptr);
-
- // Instantiate b.js, which should succeed.
- const char* b_src = "throw new Error('foo')";
- b = deno_mod_new(d, false, "b.js", b_src);
- EXPECT_NE(b, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, b, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- // Evaluate b.js. It throws in the global scope, so deno_last_exception()
- // should be non-null afterwards.
- deno_mod_evaluate(d, d, b);
- EXPECT_NE(deno_last_exception(d), nullptr);
-
- // Resolve the dynamic import of b.js. Since deno_mod_evaluate() failed,
- // we indicate failure to deno_dyn_import_done() by setting mod_id to 0.
- // The last error should be picked up and cleared by deno_dyn_import_done().
- EXPECT_EQ(1u, import_ids.size());
- auto import_id = import_ids.back();
- import_ids.pop_back();
- deno_dyn_import_done(d, d, import_id, 0, nullptr);
- EXPECT_EQ(deno_last_exception(d), nullptr);
-
- // Since the dynamically imported module threw an error,
- // it should show up as an unhandled promise rejection.
- deno_check_promise_errors(d);
- EXPECT_NE(deno_last_exception(d), nullptr);
- std::string e(deno_last_exception(d));
- EXPECT_NE(e.find("Uncaught Error: foo"), std::string::npos);
-
- EXPECT_EQ(1, dyn_import_count);
- EXPECT_EQ(0, exec_count);
-
- deno_delete(d);
-}
-
-TEST(ModulesTest, DynamicImportSyntaxError) {
- exec_count = 0;
- static int dyn_import_count = 0;
- auto dyn_import_cb = [](auto user_data, const char* specifier,
- const char* referrer, deno_dyn_import_id import_id) {
- auto d = reinterpret_cast<Deno*>(user_data);
- dyn_import_count++;
- EXPECT_STREQ(specifier, "b.js");
- EXPECT_STREQ(referrer, "a.js");
-
- // Compile b.js, which should fail because of the syntax error.
- deno_mod b = deno_mod_new(d, false, "b.js", "syntax error");
- EXPECT_EQ(b, 0);
- EXPECT_NE(nullptr, deno_last_exception(d));
-
- // `deno_dyn_import_done` should consume the last exception, and use it
- // to reject the dynamic import promise.
- deno_dyn_import_done(d, d, import_id, 0, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- };
- Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb, dyn_import_cb});
-
- // Instantiate and evaluate the root module. This should succeed.
- const char* src =
- "(async () => { \n"
- " let mod = await import('b.js'); \n"
- // unreachable
- " Deno.core.send(42, new Uint8Array([4])); \n"
- "})(); \n";
- static deno_mod a = deno_mod_new(d, true, "a.js", src);
- EXPECT_NE(a, 0);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_instantiate(d, d, a, nullptr);
- EXPECT_EQ(nullptr, deno_last_exception(d));
- deno_mod_evaluate(d, d, a);
- EXPECT_EQ(nullptr, deno_last_exception(d));
-
- // The failed dynamic import should cause an unhandled promise rejection.
- deno_check_promise_errors(d);
- EXPECT_NE(deno_last_exception(d), nullptr);
- EXPECT_NE(std::string(deno_last_exception(d)).find("Syntax"),
- std::string::npos);
-
- EXPECT_EQ(1, dyn_import_count);
- EXPECT_EQ(0, exec_count);
-
- deno_delete(d);
-}
diff --git a/core/libdeno/test.cc b/core/libdeno/test.cc
deleted file mode 100644
index 994d43d21..000000000
--- a/core/libdeno/test.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#include "test.h"
-#include <fstream>
-#include <string>
-#include "internal.h"
-
-deno_snapshot snapshot = {nullptr, 0};
-
-bool ReadFileToString(const char* fn, std::string* contents) {
- std::ifstream file(fn, std::ios::binary);
- if (file.fail()) {
- return false;
- }
- contents->assign(std::istreambuf_iterator<char>{file}, {});
- return !file.fail();
-}
-
-int main(int argc, char** argv) {
- // All of the JS code in libdeno_test.js is tested after being snapshotted.
- // We create that snapshot now at runtime, rather than at compile time to
- // simplify the build process. So we load and execute the libdeno_test.js
- // file, without running any of the tests and store the result in the global
- // "snapshot" variable, which will be used later in the tests.
- std::string js_fn = JS_PATH;
- std::string js_source;
- CHECK(ReadFileToString(js_fn.c_str(), &js_source));
-
- deno_init();
- deno_config config = {1, deno::empty_snapshot, deno::empty_buf, nullptr,
- nullptr};
- Deno* d = deno_new(config);
-
- deno_execute(d, nullptr, js_fn.c_str(), js_source.c_str());
- if (deno_last_exception(d) != nullptr) {
- std::cerr << "Snapshot Exception " << std::endl;
- std::cerr << deno_last_exception(d) << std::endl;
- deno_delete(d);
- return 1;
- }
-
- snapshot = deno_snapshot_new(d);
-
- testing::InitGoogleTest(&argc, argv);
- deno_init();
- deno_set_v8_flags(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/core/libdeno/test.h b/core/libdeno/test.h
deleted file mode 100644
index 4d7b73ab3..000000000
--- a/core/libdeno/test.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#ifndef TEST_H_
-#define TEST_H_
-
-#include "deno.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-extern deno_snapshot snapshot; // Loaded in libdeno/test.cc
-const deno_buf empty = {nullptr, 0};
-const deno_snapshot empty_snapshot = {nullptr, 0};
-
-#endif // TEST_H_
diff --git a/core/libdeno/testing b/core/libdeno/testing
deleted file mode 120000
index ed34f4824..000000000
--- a/core/libdeno/testing
+++ /dev/null
@@ -1 +0,0 @@
-v8/testing \ No newline at end of file
diff --git a/core/libdeno/third_party b/core/libdeno/third_party
deleted file mode 120000
index 48370cbe7..000000000
--- a/core/libdeno/third_party
+++ /dev/null
@@ -1 +0,0 @@
-v8/third_party \ No newline at end of file
diff --git a/core/libdeno/tools b/core/libdeno/tools
deleted file mode 120000
index 7b6c53ae9..000000000
--- a/core/libdeno/tools
+++ /dev/null
@@ -1 +0,0 @@
-v8/tools \ No newline at end of file
diff --git a/core/libdeno/v8 b/core/libdeno/v8
deleted file mode 120000
index efdcb44da..000000000
--- a/core/libdeno/v8
+++ /dev/null
@@ -1 +0,0 @@
-../../third_party/v8 \ No newline at end of file