diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binding.cc | 415 | ||||
-rw-r--r-- | src/deno.h | 65 | ||||
-rw-r--r-- | src/file_util.cc | 31 | ||||
-rw-r--r-- | src/file_util.h | 12 | ||||
-rw-r--r-- | src/file_util_test.cc | 21 | ||||
-rw-r--r-- | src/from_filesystem.cc | 56 | ||||
-rw-r--r-- | src/from_snapshot.cc | 86 | ||||
-rw-r--r-- | src/internal.h | 44 | ||||
-rw-r--r-- | src/libdeno_test.cc | 201 | ||||
-rw-r--r-- | src/snapshot_creator.cc | 75 | ||||
-rw-r--r-- | src/test.cc | 10 |
11 files changed, 0 insertions, 1016 deletions
diff --git a/src/binding.cc b/src/binding.cc deleted file mode 100644 index 0a107c95f..000000000 --- a/src/binding.cc +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <string> - -#include "third_party/v8/include/libplatform/libplatform.h" -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -#include "deno.h" -#include "internal.h" - -namespace deno { - -static bool skip_onerror = false; - -Deno* FromIsolate(v8::Isolate* isolate) { - return static_cast<Deno*>(isolate->GetData(0)); -} - -// Extracts a C string from a v8::V8 Utf8Value. -const char* ToCString(const v8::String::Utf8Value& value) { - return *value ? *value : "<string conversion failed>"; -} - -static inline v8::Local<v8::String> v8_str(const char* x) { - return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), x, - v8::NewStringType::kNormal) - .ToLocalChecked(); -} - -void HandleExceptionStr(v8::Local<v8::Context> context, - v8::Local<v8::Value> exception, - std::string* exception_str) { - auto* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Context::Scope context_scope(context); - - auto message = v8::Exception::CreateMessage(isolate, exception); - auto onerrorStr = v8::String::NewFromUtf8(isolate, "onerror"); - auto onerror = context->Global()->Get(onerrorStr); - auto stack_trace = message->GetStackTrace(); - auto line = - v8::Integer::New(isolate, message->GetLineNumber(context).FromJust()); - auto column = - v8::Integer::New(isolate, message->GetStartColumn(context).FromJust()); - - if (skip_onerror == false) { - if (onerror->IsFunction()) { - // window.onerror is set so we try to handle the exception in javascript. - auto func = v8::Local<v8::Function>::Cast(onerror); - v8::Local<v8::Value> args[5]; - args[0] = exception->ToString(); - args[1] = message->GetScriptResourceName(); - args[2] = line; - args[3] = column; - args[4] = exception; - func->Call(context->Global(), 5, args); - /* message, source, lineno, colno, error */ - } - } - - char buf[12 * 1024]; - if (!stack_trace.IsEmpty()) { - // No javascript onerror handler, but we do have a stack trace. Format it - // into a string and add to last_exception. - std::string msg; - v8::String::Utf8Value exceptionStr(isolate, exception); - msg += ToCString(exceptionStr); - msg += "\n"; - - for (int i = 0; i < stack_trace->GetFrameCount(); ++i) { - auto frame = stack_trace->GetFrame(i); - v8::String::Utf8Value script_name(isolate, frame->GetScriptName()); - int l = frame->GetLineNumber(); - int c = frame->GetColumn(); - snprintf(buf, sizeof(buf), "%s %d:%d\n", ToCString(script_name), l, c); - msg += buf; - } - *exception_str += msg; - } else { - // No javascript onerror handler, no stack trace. Format the little info we - // have into a string and add to last_exception. - v8::String::Utf8Value exceptionStr(isolate, exception); - v8::String::Utf8Value script_name(isolate, - message->GetScriptResourceName()); - v8::String::Utf8Value line_str(isolate, line); - v8::String::Utf8Value col_str(isolate, column); - snprintf(buf, sizeof(buf), "%s\n%s %s:%s\n", ToCString(exceptionStr), - ToCString(script_name), ToCString(line_str), ToCString(col_str)); - *exception_str += buf; - } -} - -void HandleException(v8::Local<v8::Context> context, - v8::Local<v8::Value> exception) { - v8::Isolate* isolate = context->GetIsolate(); - Deno* d = FromIsolate(isolate); - std::string exception_str; - HandleExceptionStr(context, exception, &exception_str); - if (d != nullptr) { - d->last_exception = exception_str; - } else { - printf("Pre-Deno Exception %s\n", exception_str.c_str()); - exit(1); - } -} - -/* -bool AbortOnUncaughtExceptionCallback(v8::Isolate* isolate) { - return true; -} - -void MessageCallback2(Local<Message> message, v8::Local<v8::Value> data) { - printf("MessageCallback2\n\n"); -} - -void FatalErrorCallback2(const char* location, const char* message) { - printf("FatalErrorCallback2\n"); -} -*/ - -void ExitOnPromiseRejectCallback( - v8::PromiseRejectMessage promise_reject_message) { - auto* isolate = v8::Isolate::GetCurrent(); - Deno* d = static_cast<Deno*>(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - v8::HandleScope handle_scope(d->isolate); - auto exception = promise_reject_message.GetValue(); - auto context = d->context.Get(d->isolate); - HandleException(context, exception); -} - -void Print(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ(args.Length(), 1); - auto* isolate = args.GetIsolate(); - v8::HandleScope handle_scope(isolate); - v8::String::Utf8Value str(isolate, args[0]); - const char* cstr = ToCString(str); - printf("%s\n", cstr); - fflush(stdout); -} - -static v8::Local<v8::Uint8Array> ImportBuf(v8::Isolate* isolate, deno_buf buf) { - if (buf.alloc_ptr == nullptr) { - // If alloc_ptr isn't set, we memcpy. - // This is currently used for flatbuffers created in Rust. - auto ab = v8::ArrayBuffer::New(isolate, buf.data_len); - memcpy(ab->GetContents().Data(), buf.data_ptr, buf.data_len); - auto view = v8::Uint8Array::New(ab, 0, buf.data_len); - return view; - } else { - auto ab = v8::ArrayBuffer::New( - isolate, reinterpret_cast<void*>(buf.alloc_ptr), buf.alloc_len, - v8::ArrayBufferCreationMode::kInternalized); - auto view = - v8::Uint8Array::New(ab, buf.data_ptr - buf.alloc_ptr, buf.data_len); - return view; - } -} - -static deno_buf ExportBuf(v8::Isolate* isolate, - v8::Local<v8::ArrayBufferView> view) { - auto ab = view->Buffer(); - auto contents = ab->Externalize(); - - deno_buf buf; - buf.alloc_ptr = reinterpret_cast<uint8_t*>(contents.Data()); - buf.alloc_len = contents.ByteLength(); - buf.data_ptr = buf.alloc_ptr + view->ByteOffset(); - buf.data_len = view->ByteLength(); - - // Prevent JS from modifying buffer contents after exporting. - ab->Neuter(); - - return buf; -} - -static void FreeBuf(deno_buf buf) { free(buf.alloc_ptr); } - -// Sets the recv callback. -void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::Isolate* isolate = args.GetIsolate(); - Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - - v8::HandleScope handle_scope(isolate); - - if (!d->recv.IsEmpty()) { - isolate->ThrowException(v8_str("deno.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(); - Deno* d = static_cast<Deno*>(isolate->GetData(0)); - DCHECK_EQ(d->isolate, isolate); - - v8::Locker locker(d->isolate); - v8::EscapableHandleScope handle_scope(isolate); - - CHECK_EQ(args.Length(), 1); - v8::Local<v8::Value> ab_v = args[0]; - CHECK(ab_v->IsArrayBufferView()); - auto buf = ExportBuf(isolate, v8::Local<v8::ArrayBufferView>::Cast(ab_v)); - - DCHECK_EQ(d->currentArgs, nullptr); - d->currentArgs = &args; - - d->cb(d, buf); - - // Buffer is only valid until the end of the callback. - // TODO(piscisaureus): - // It's possible that data in the buffer is needed after the callback - // returns, e.g. when the handler offloads work to a thread pool, therefore - // make the callback responsible for releasing the buffer. - FreeBuf(buf); - - d->currentArgs = nullptr; -} - -bool ExecuteV8StringSource(v8::Local<v8::Context> context, - const char* js_filename, - v8::Local<v8::String> source) { - auto* isolate = context->GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - - v8::Context::Scope context_scope(context); - - v8::TryCatch try_catch(isolate); - - auto name = v8_str(js_filename); - - 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; -} - -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); - auto source = v8_str(js_source); - return ExecuteV8StringSource(context, js_filename, source); -} - -void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context, - const char* js_filename, const std::string& js_source, - const std::string* source_map) { - 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("libdeno"), deno_val).FromJust()); - - auto print_tmpl = v8::FunctionTemplate::New(isolate, Print); - auto print_val = print_tmpl->GetFunction(context).ToLocalChecked(); - CHECK(deno_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(deno_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(deno_val->Set(context, deno::v8_str("send"), send_val).FromJust()); - - skip_onerror = true; - { - auto source = deno::v8_str(js_source.c_str()); - CHECK( - deno_val->Set(context, deno::v8_str("mainSource"), source).FromJust()); - - bool r = deno::ExecuteV8StringSource(context, js_filename, source); - CHECK(r); - - if (source_map != nullptr) { - CHECK_GT(source_map->length(), 1u); - v8::TryCatch try_catch(isolate); - v8::ScriptOrigin origin(v8_str("set_source_map.js")); - std::string source_map_parens = "(" + *source_map + ")"; - auto source_map_v8_str = deno::v8_str(source_map_parens.c_str()); - auto script = v8::Script::Compile(context, source_map_v8_str, &origin); - if (script.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - HandleException(context, try_catch.Exception()); - return; - } - auto source_map_obj = script.ToLocalChecked()->Run(context); - if (source_map_obj.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - HandleException(context, try_catch.Exception()); - return; - } - CHECK(deno_val - ->Set(context, deno::v8_str("mainSourceMap"), - source_map_obj.ToLocalChecked()) - .FromJust()); - } - } - skip_onerror = false; -} - -void AddIsolate(Deno* d, v8::Isolate* isolate) { - d->isolate = isolate; - // Leaving this code here because it will probably be useful later on, but - // disabling it now as I haven't got tests for the desired behavior. - // d->isolate->SetCaptureStackTraceForUncaughtExceptions(true); - // d->isolate->SetAbortOnUncaughtExceptionCallback(AbortOnUncaughtExceptionCallback); - // d->isolate->AddMessageListener(MessageCallback2); - // d->isolate->SetFatalErrorHandler(FatalErrorCallback2); - d->isolate->SetPromiseRejectCallback(deno::ExitOnPromiseRejectCallback); - d->isolate->SetData(0, d); -} - -} // namespace deno - -extern "C" { - -void deno_init() { - // v8::V8::InitializeICUDefaultLocation(argv[0]); - // v8::V8::InitializeExternalStartupData(argv[0]); - auto* p = v8::platform::CreateDefaultPlatform(); - v8::V8::InitializePlatform(p); - v8::V8::Initialize(); -} - -void* deno_get_data(Deno* d) { return d->data; } - -const char* deno_v8_version() { return v8::V8::GetVersion(); } - -void deno_set_flags(int* argc, char** argv) { - v8::V8::SetFlagsFromCommandLine(argc, argv, true); -} - -const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); } - -int deno_execute(Deno* d, const char* js_filename, const char* js_source) { - auto* isolate = d->isolate; - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope handle_scope(isolate); - auto context = d->context.Get(d->isolate); - return deno::Execute(context, js_filename, js_source) ? 1 : 0; -} - -int deno_send(Deno* d, deno_buf buf) { - v8::Locker locker(d->isolate); - v8::Isolate::Scope isolate_scope(d->isolate); - v8::HandleScope handle_scope(d->isolate); - - auto context = d->context.Get(d->isolate); - v8::Context::Scope context_scope(context); - - v8::TryCatch try_catch(d->isolate); - - auto recv = d->recv.Get(d->isolate); - if (recv.IsEmpty()) { - d->last_exception = "deno.recv has not been called."; - return 0; - } - - v8::Local<v8::Value> args[1]; - args[0] = deno::ImportBuf(d->isolate, buf); - recv->Call(context->Global(), 1, args); - - if (try_catch.HasCaught()) { - deno::HandleException(context, try_catch.Exception()); - return 0; - } - - return 1; -} - -void deno_set_response(Deno* d, deno_buf buf) { - auto ab = deno::ImportBuf(d->isolate, buf); - d->currentArgs->GetReturnValue().Set(ab); -} - -void deno_delete(Deno* d) { - d->isolate->Dispose(); - delete d; -} - -void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); } - -} // extern "C" diff --git a/src/deno.h b/src/deno.h deleted file mode 100644 index 7bde5ab9d..000000000 --- a/src/deno.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#ifndef DENO_H_ -#define DENO_H_ -#include <stddef.h> -#include <stdint.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 - -// Data that gets transmitted. -typedef struct { - uint8_t* alloc_ptr; // Start of memory allocation (returned from `malloc()`). - size_t alloc_len; // Length of the memory allocation. - uint8_t* data_ptr; // Start of logical contents (within the allocation). - size_t data_len; // Length of logical contents. -} deno_buf; - -struct deno_s; -typedef struct deno_s Deno; - -// A callback to receive a message from deno.send javascript call. -// buf is valid only for the lifetime of the call. -typedef void (*deno_recv_cb)(Deno* d, deno_buf buf); - -void deno_init(); -const char* deno_v8_version(); -void deno_set_flags(int* argc, char** argv); - -Deno* deno_new(void* data, deno_recv_cb cb); -void deno_delete(Deno* d); - -// Returns the void* data provided in deno_new. -void* deno_get_data(Deno*); - -// Returns false on error. -// Get error text with deno_last_exception(). -// 0 = fail, 1 = success -int deno_execute(Deno* d, const char* js_filename, const char* js_source); - -// Routes message to the javascript callback set with deno.recv(). A false -// return value indicates error. Check deno_last_exception() for exception text. -// 0 = fail, 1 = success -// After calling deno_send(), the caller no longer owns `buf` and must not use -// it; deno_send() is responsible for releasing it's memory. -// TODO(piscisaureus) In C++ and/or Rust, use a smart pointer or similar to -// enforce this rule. -int deno_send(Deno* d, deno_buf buf); - -// Call this inside a deno_recv_cb to respond synchronously to messages. -// If this is not called during the life time of a deno_recv_cb callback -// the deno.send() call in javascript will return null. -// After calling deno_set_response(), the caller no longer owns `buf` and must -// not access it; deno_set_response() is responsible for releasing it's memory. -void deno_set_response(Deno* d, deno_buf buf); - -const char* deno_last_exception(Deno* d); - -void deno_terminate_execution(Deno* d); - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // DENO_H_ diff --git a/src/file_util.cc b/src/file_util.cc deleted file mode 100644 index a0cae5f58..000000000 --- a/src/file_util.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include <inttypes.h> -#include <stdio.h> -#include <fstream> -#include <iterator> -#include <string> - -#include "file_util.h" - -namespace deno { - -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(); -} - -std::string Basename(std::string const& filename) { - for (auto it = filename.rbegin(); it != filename.rend(); ++it) { - char ch = *it; - if (ch == '\\' || ch == '/') { - return std::string(it.base(), filename.end()); - } - } - return filename; -} - -} // namespace deno diff --git a/src/file_util.h b/src/file_util.h deleted file mode 100644 index c8c0e5759..000000000 --- a/src/file_util.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#ifndef FILE_UTIL_H_ -#define FILE_UTIL_H_ - -#include <string> - -namespace deno { -bool ReadFileToString(const char* fn, std::string* contents); -std::string Basename(std::string const& filename); -} // namespace deno - -#endif // FILE_UTIL_H_ diff --git a/src/file_util_test.cc b/src/file_util_test.cc deleted file mode 100644 index 3f01c8115..000000000 --- a/src/file_util_test.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include "testing/gtest/include/gtest/gtest.h" - -#include "file_util.h" - -TEST(FileUtilTest, ReadFileToStringFileNotExist) { - std::string output; - EXPECT_FALSE(deno::ReadFileToString("/should_error_out.txt", &output)); -} - -TEST(FileUtilTest, Basename) { - EXPECT_EQ("foo.txt", deno::Basename("foo.txt")); - EXPECT_EQ("foo.txt", deno::Basename("/foo.txt")); - EXPECT_EQ("", deno::Basename("/")); - EXPECT_EQ("foo.txt", deno::Basename(".\\foo.txt")); - EXPECT_EQ("foo.txt", deno::Basename("/home/ryan/foo.txt")); - EXPECT_EQ("foo.txt", deno::Basename("C:\\home\\ryan\\foo.txt")); -} - -// TODO(ry) success unit test. Needs a tempfile or fixture. -// TEST(FileUtilTest, ReadFileToStringSuccess) { } diff --git a/src/from_filesystem.cc b/src/from_filesystem.cc deleted file mode 100644 index fa50c0515..000000000 --- a/src/from_filesystem.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// This file is used to load the bundle at start for deno_ns. -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <string> - -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -#include "deno.h" -#include "file_util.h" -#include "internal.h" - -namespace deno { - -Deno* NewFromFileSystem(void* data, deno_recv_cb cb) { - std::string js_source; - CHECK(deno::ReadFileToString(BUNDLE_LOCATION, &js_source)); - - std::string js_source_map; - CHECK(deno::ReadFileToString(BUNDLE_MAP_LOCATION, &js_source_map)); - - Deno* d = new Deno; - d->currentArgs = nullptr; - d->cb = cb; - d->data = data; - v8::Isolate::CreateParams params; - params.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); - v8::Isolate* isolate = v8::Isolate::New(params); - AddIsolate(d, isolate); - - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - { - v8::HandleScope handle_scope(isolate); - auto context = v8::Context::New(isolate); - // BUNDLE_LOCATION is absolute so deno_ns can load the bundle independently - // of the cwd. However for source maps to work, the bundle location relative - // to the build path must be supplied: BUNDLE_REL_LOCATION. - InitializeContext(isolate, context, BUNDLE_REL_LOCATION, js_source, - &js_source_map); - d->context.Reset(d->isolate, context); - } - - return d; -} - -} // namespace deno - -extern "C" { -Deno* deno_new(void* data, deno_recv_cb cb) { - return deno::NewFromFileSystem(data, cb); -} -} diff --git a/src/from_snapshot.cc b/src/from_snapshot.cc deleted file mode 100644 index bcd215f82..000000000 --- a/src/from_snapshot.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <string> - -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -#include "deno.h" -#include "internal.h" - -extern const char deno_snapshot_start asm("deno_snapshot_start"); -extern const char deno_snapshot_end asm("deno_snapshot_end"); -#ifdef LIBDENO_TEST -asm(".data\n" - "deno_snapshot_start: .incbin \"gen/snapshot_libdeno_test.bin\"\n" - "deno_snapshot_end:\n" - ".globl deno_snapshot_start;\n" - ".globl deno_snapshot_end;"); -#else -asm(".data\n" - "deno_snapshot_start: .incbin \"gen/snapshot_deno.bin\"\n" - "deno_snapshot_end:\n" - ".globl deno_snapshot_start;\n" - ".globl deno_snapshot_end;"); -#endif // LIBDENO_TEST - -namespace deno { - -std::vector<InternalFieldData*> deserialized_data; - -void DeserializeInternalFields(v8::Local<v8::Object> holder, int index, - v8::StartupData payload, void* data) { - DCHECK_EQ(data, nullptr); - if (payload.raw_size == 0) { - holder->SetAlignedPointerInInternalField(index, nullptr); - return; - } - InternalFieldData* embedder_field = new InternalFieldData{0}; - memcpy(embedder_field, payload.data, payload.raw_size); - holder->SetAlignedPointerInInternalField(index, embedder_field); - deserialized_data.push_back(embedder_field); -} - -Deno* NewFromSnapshot(void* data, deno_recv_cb cb) { - Deno* d = new Deno; - d->currentArgs = nullptr; - d->cb = cb; - d->data = data; - v8::Isolate::CreateParams params; - params.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); - params.external_references = external_references; - - CHECK_NE(&deno_snapshot_start, nullptr); - int snapshot_len = - static_cast<int>(&deno_snapshot_end - &deno_snapshot_start); - static v8::StartupData snapshot = {&deno_snapshot_start, snapshot_len}; - params.snapshot_blob = &snapshot; - - v8::Isolate* isolate = v8::Isolate::New(params); - AddIsolate(d, 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( - DeserializeInternalFields, nullptr)); - d->context.Reset(d->isolate, context); - } - - return d; -} - -} // namespace deno - -extern "C" { -Deno* deno_new(void* data, deno_recv_cb cb) { - return deno::NewFromSnapshot(data, cb); -} -} diff --git a/src/internal.h b/src/internal.h deleted file mode 100644 index c63ba532a..000000000 --- a/src/internal.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#ifndef INTERNAL_H_ -#define INTERNAL_H_ - -#include <string> -#include "deno.h" -#include "third_party/v8/include/v8.h" - -extern "C" { -// deno_s = Wrapped Isolate. -struct deno_s { - v8::Isolate* isolate; - const v8::FunctionCallbackInfo<v8::Value>* currentArgs; - std::string last_exception; - v8::Persistent<v8::Function> recv; - v8::Persistent<v8::Context> context; - deno_recv_cb cb; - void* data; -}; -} - -namespace deno { - -struct InternalFieldData { - uint32_t data; -}; - -void Print(const v8::FunctionCallbackInfo<v8::Value>& args); -void Recv(const v8::FunctionCallbackInfo<v8::Value>& args); -void Send(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), 0}; - -Deno* NewFromSnapshot(void* data, deno_recv_cb cb); - -void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context, - const char* js_filename, const std::string& js_source, - const std::string* source_map); - -void AddIsolate(Deno* d, v8::Isolate* isolate); - -} // namespace deno -#endif // INTERNAL_H_ diff --git a/src/libdeno_test.cc b/src/libdeno_test.cc deleted file mode 100644 index 4675e4d7b..000000000 --- a/src/libdeno_test.cc +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include "testing/gtest/include/gtest/gtest.h" - -#include "deno.h" - -TEST(LibDenoTest, InitializesCorrectly) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "1 + 2")); - deno_delete(d); -} - -TEST(LibDenoTest, CanCallFunction) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", - "if (CanCallFunction() != 'foo') throw Error();")); - deno_delete(d); -} - -TEST(LibDenoTest, ErrorsCorrectly) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_FALSE(deno_execute(d, "a.js", "throw Error()")); - deno_delete(d); -} - -deno_buf strbuf(const char* str) { - auto len = strlen(str); - - deno_buf buf; - buf.alloc_ptr = reinterpret_cast<uint8_t*>(strdup(str)); - buf.alloc_len = len + 1; - buf.data_ptr = buf.alloc_ptr; - buf.data_len = len; - - return buf; -} - -// Same as strbuf but with null alloc_ptr. -deno_buf StrBufNullAllocPtr(const char* str) { - auto len = strlen(str); - deno_buf buf; - buf.alloc_ptr = nullptr; - buf.alloc_len = 0; - buf.data_ptr = reinterpret_cast<uint8_t*>(strdup(str)); - buf.data_len = len; - return buf; -} - -TEST(LibDenoTest, SendSuccess) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "SendSuccess()")); - EXPECT_TRUE(deno_send(d, strbuf("abc"))); - deno_delete(d); -} - -TEST(LibDenoTest, SendWrongByteLength) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "SendWrongByteLength()")); - // deno_send the wrong sized message, it should throw. - EXPECT_FALSE(deno_send(d, strbuf("abcd"))); - std::string exception = deno_last_exception(d); - EXPECT_GT(exception.length(), 1u); - EXPECT_NE(exception.find("assert"), std::string::npos); - deno_delete(d); -} - -TEST(LibDenoTest, SendNoCallback) { - Deno* d = deno_new(nullptr, nullptr); - // We didn't call deno.recv() in JS, should fail. - EXPECT_FALSE(deno_send(d, strbuf("abc"))); - deno_delete(d); -} - -TEST(LibDenoTest, RecvReturnEmpty) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto 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'); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "RecvReturnEmpty()")); - EXPECT_EQ(count, 2); - deno_delete(d); -} - -TEST(LibDenoTest, RecvReturnBar) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto deno, auto 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_set_response(deno, strbuf("bar")); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "RecvReturnBar()")); - EXPECT_EQ(count, 1); - deno_delete(d); -} - -TEST(LibDenoTest, DoubleRecvFails) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_FALSE(deno_execute(d, "a.js", "DoubleRecvFails()")); - deno_delete(d); -} - -TEST(LibDenoTest, SendRecvSlice) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto deno, auto buf) { - static const size_t alloc_len = 1024; - size_t i = count++; - // Check the size and offset of the slice. - size_t data_offset = buf.data_ptr - buf.alloc_ptr; - EXPECT_EQ(data_offset, i * 11); - EXPECT_EQ(buf.data_len, alloc_len - i * 30); - EXPECT_EQ(buf.alloc_len, alloc_len); - // Check values written by the JS side. - EXPECT_EQ(buf.data_ptr[0], 100 + i); - EXPECT_EQ(buf.data_ptr[buf.data_len - 1], 100 - i); - // Make copy of the backing buffer -- this is currently necessary because - // deno_set_response() takes ownership over the buffer, but we are not given - // ownership of `buf` by our caller. - uint8_t* alloc_ptr = reinterpret_cast<uint8_t*>(malloc(alloc_len)); - memcpy(alloc_ptr, buf.alloc_ptr, alloc_len); - // Make a slice that is a bit shorter than the original. - deno_buf buf2{alloc_ptr, alloc_len, alloc_ptr + data_offset, - buf.data_len - 19}; - // Place some values into the buffer for the JS side to verify. - buf2.data_ptr[0] = 200 + i; - buf2.data_ptr[buf2.data_len - 1] = 200 - i; - // Send back. - deno_set_response(deno, buf2); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "SendRecvSlice()")); - EXPECT_EQ(count, 5); - deno_delete(d); -} - -TEST(LibDenoTest, JSSendArrayBufferViewTypes) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { - count++; - size_t data_offset = buf.data_ptr - buf.alloc_ptr; - EXPECT_EQ(data_offset, 2468u); - EXPECT_EQ(buf.data_len, 1000u); - EXPECT_EQ(buf.alloc_len, 4321u); - EXPECT_EQ(buf.data_ptr[0], count); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "JSSendArrayBufferViewTypes()")); - EXPECT_EQ(count, 3); - deno_delete(d); -} - -TEST(LibDenoTest, JSSendNeutersBuffer) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { - count++; - EXPECT_EQ(buf.data_len, 1u); - EXPECT_EQ(buf.data_ptr[0], 42); - }); - EXPECT_TRUE(deno_execute(d, "a.js", "JSSendNeutersBuffer()")); - EXPECT_EQ(count, 1); - deno_delete(d); -} - -TEST(LibDenoTest, TypedArraySnapshots) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "TypedArraySnapshots()")); - deno_delete(d); -} - -TEST(LibDenoTest, SnapshotBug) { - Deno* d = deno_new(nullptr, nullptr); - EXPECT_TRUE(deno_execute(d, "a.js", "SnapshotBug()")); - deno_delete(d); -} - -TEST(LibDenoTest, ErrorHandling) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto deno, auto buf) { - count++; - EXPECT_EQ(static_cast<size_t>(1), buf.data_len); - EXPECT_EQ(buf.data_ptr[0], 42); - }); - EXPECT_FALSE(deno_execute(d, "a.js", "ErrorHandling()")); - EXPECT_EQ(count, 1); - deno_delete(d); -} - -TEST(LibDenoTest, SendNullAllocPtr) { - static int count = 0; - Deno* d = deno_new(nullptr, [](auto _, auto buf) { count++; }); - EXPECT_TRUE(deno_execute(d, "a.js", "SendNullAllocPtr()")); - deno_buf buf = StrBufNullAllocPtr("abcd"); - EXPECT_EQ(buf.alloc_ptr, nullptr); - EXPECT_EQ(buf.data_len, 4u); - EXPECT_TRUE(deno_send(d, buf)); - EXPECT_EQ(count, 0); - deno_delete(d); -} diff --git a/src/snapshot_creator.cc b/src/snapshot_creator.cc deleted file mode 100644 index 8038c9b13..000000000 --- a/src/snapshot_creator.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -// Hint: --trace_serializer is a useful debugging flag. -#include <fstream> -#include "deno.h" -#include "file_util.h" -#include "internal.h" -#include "third_party/v8/include/v8.h" -#include "third_party/v8/src/base/logging.h" - -namespace deno { - -v8::StartupData SerializeInternalFields(v8::Local<v8::Object> holder, int index, - void* data) { - DCHECK_EQ(data, nullptr); - 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}; -} - -v8::StartupData MakeSnapshot(const char* js_filename, - const std::string& js_source, - const std::string* source_map) { - auto* creator = new v8::SnapshotCreator(external_references); - auto* isolate = creator->GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - { - v8::HandleScope handle_scope(isolate); - auto context = v8::Context::New(isolate); - InitializeContext(isolate, context, js_filename, js_source, source_map); - creator->SetDefaultContext(context, v8::SerializeInternalFieldsCallback( - SerializeInternalFields, nullptr)); - } - - auto snapshot_blob = - creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kClear); - - return snapshot_blob; -} - -} // namespace deno - -int main(int argc, char** argv) { - const char* snapshot_out_bin = argv[1]; - const char* js_fn = argv[2]; - const char* source_map_fn = argv[3]; // Optional. - - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - - CHECK_NE(js_fn, nullptr); - CHECK_NE(snapshot_out_bin, nullptr); - - std::string js_source; - CHECK(deno::ReadFileToString(js_fn, &js_source)); - - std::string source_map; - if (source_map_fn != nullptr) { - CHECK_EQ(argc, 4); - CHECK(deno::ReadFileToString(source_map_fn, &source_map)); - } - - deno_init(); - auto snapshot_blob = deno::MakeSnapshot( - js_fn, js_source, source_map_fn != nullptr ? &source_map : nullptr); - std::string snapshot_str(snapshot_blob.data, snapshot_blob.raw_size); - - std::ofstream file_(snapshot_out_bin, std::ios::binary); - file_ << snapshot_str; - file_.close(); - return file_.bad(); -} diff --git a/src/test.cc b/src/test.cc deleted file mode 100644 index 9638dba60..000000000 --- a/src/test.cc +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2018 the Deno authors. All rights reserved. MIT license. -#include "deno.h" -#include "testing/gtest/include/gtest/gtest.h" - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - deno_init(); - deno_set_flags(&argc, argv); - return RUN_ALL_TESTS(); -} |