summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdeno/api.cc59
-rw-r--r--libdeno/binding.cc21
-rw-r--r--libdeno/deno.h11
-rw-r--r--libdeno/internal.h12
-rw-r--r--libdeno/libdeno_test.cc41
-rw-r--r--libdeno/snapshot_creator.cc13
-rw-r--r--src/isolate.rs4
-rw-r--r--src/libdeno.rs4
8 files changed, 85 insertions, 80 deletions
diff --git a/libdeno/api.cc b/libdeno/api.cc
index 388ab6146..472181819 100644
--- a/libdeno/api.cc
+++ b/libdeno/api.cc
@@ -13,13 +13,40 @@
extern "C" {
-Deno* deno_new(deno_buf snapshot, deno_config config) {
- deno::DenoIsolate* d = new deno::DenoIsolate(snapshot, config);
+Deno* deno_new_snapshotter(deno_config config) {
+ CHECK(config.will_snapshot);
+ // TODO 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 = d->array_buffer_allocator_;
params.external_references = deno::external_references;
- if (snapshot.data_ptr) {
+ if (config.load_snapshot.data_ptr) {
params.snapshot_blob = &d->snapshot_;
}
@@ -35,10 +62,10 @@ Deno* deno_new(deno_buf snapshot, deno_config config) {
v8::MaybeLocal<v8::Value>(),
v8::DeserializeInternalFieldsCallback(
deno::DeserializeInternalFields, nullptr));
- if (!snapshot.data_ptr) {
+ 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, "", "");
+ deno::InitializeContext(isolate, context);
}
d->context_.Reset(isolate, context);
}
@@ -46,26 +73,6 @@ Deno* deno_new(deno_buf snapshot, deno_config config) {
return reinterpret_cast<Deno*>(d);
}
-Deno* deno_new_snapshotter(deno_config config, const char* js_filename,
- const char* js_source) {
- auto* creator = new v8::SnapshotCreator(deno::external_references);
- auto* isolate = creator->GetIsolate();
- auto* d = new deno::DenoIsolate(deno::empty_buf, 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);
- creator->SetDefaultContext(context,
- v8::SerializeInternalFieldsCallback(
- deno::SerializeInternalFields, nullptr));
- deno::InitializeContext(isolate, context, js_filename, js_source);
- }
- return reinterpret_cast<Deno*>(d);
-}
-
deno::DenoIsolate* unwrap(Deno* d_) {
return reinterpret_cast<deno::DenoIsolate*>(d_);
}
@@ -73,6 +80,7 @@ deno::DenoIsolate* unwrap(Deno* d_) {
deno_buf deno_get_snapshot(Deno* d_) {
auto* d = unwrap(d_);
CHECK_NE(d->snapshot_creator_, nullptr);
+ d->context_.Reset();
auto blob = d->snapshot_creator_->CreateBlob(
v8::SnapshotCreator::FunctionCodeHandling::kClear);
return {nullptr, 0, reinterpret_cast<uint8_t*>(const_cast<char*>(blob.data)),
@@ -111,6 +119,7 @@ int deno_execute(Deno* d_, void* user_data, const char* js_filename,
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
auto context = d->context_.Get(d->isolate_);
+ CHECK(!context.IsEmpty());
return deno::Execute(context, js_filename, js_source) ? 1 : 0;
}
diff --git a/libdeno/binding.cc b/libdeno/binding.cc
index 2a68d89aa..bb931ca1d 100644
--- a/libdeno/binding.cc
+++ b/libdeno/binding.cc
@@ -154,13 +154,8 @@ void HandleException(v8::Local<v8::Context> context,
v8::Isolate* isolate = context->GetIsolate();
DenoIsolate* d = FromIsolate(isolate);
std::string json_str = EncodeExceptionAsJSON(context, exception);
- if (d != nullptr) {
- d->last_exception_ = json_str;
- } else {
- // This shouldn't happen in normal circumstances. Added for debugging.
- std::cerr << "Pre-Deno Exception " << json_str << std::endl;
- CHECK(false);
- }
+ CHECK(d != nullptr);
+ d->last_exception_ = json_str;
}
void PromiseRejectCallback(v8::PromiseRejectMessage promise_reject_message) {
@@ -396,10 +391,7 @@ bool Execute(v8::Local<v8::Context> context, const char* js_filename,
return ExecuteV8StringSource(context, js_filename, source);
}
-void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
- const char* js_filename, const char* js_source) {
- CHECK_NE(js_source, nullptr);
- CHECK_NE(js_filename, nullptr);
+void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
@@ -422,13 +414,6 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
CHECK(deno_val->SetAccessor(context, deno::v8_str("shared"), Shared)
.FromJust());
-
- {
- auto source = deno::v8_str(js_source);
-
- bool r = deno::ExecuteV8StringSource(context, js_filename, source);
- CHECK(r);
- }
}
void DenoIsolate::AddIsolate(v8::Isolate* isolate) {
diff --git a/libdeno/deno.h b/libdeno/deno.h
index 48356bc86..e0ba63153 100644
--- a/libdeno/deno.h
+++ b/libdeno/deno.h
@@ -30,14 +30,13 @@ const char* deno_v8_version();
void deno_set_v8_flags(int* argc, char** argv);
typedef struct {
- deno_buf shared; // Shared buffer to be mapped to libdeno.shared
- deno_recv_cb recv_cb; // Maps to libdeno.send() calls.
+ int will_snapshot; // Default 0. If calling deno_get_snapshot 1.
+ deno_buf load_snapshot; // Optionally: A deno_buf from deno_get_snapshot.
+ deno_buf shared; // Shared buffer to be mapped to libdeno.shared
+ deno_recv_cb recv_cb; // Maps to libdeno.send() calls.
} deno_config;
-Deno* deno_new(deno_buf snapshot, deno_config config);
-
-Deno* deno_new_snapshotter(deno_config config, const char* js_filename,
- const char* js_source);
+Deno* deno_new(deno_config config);
// Generate a snapshot. The resulting buf can be used with deno_new.
// The caller must free the returned data by calling delete[] buf.data_ptr.
diff --git a/libdeno/internal.h b/libdeno/internal.h
index 3dc4d8d0e..782108d98 100644
--- a/libdeno/internal.h
+++ b/libdeno/internal.h
@@ -13,7 +13,7 @@ namespace deno {
// deno_s = Wrapped Isolate.
class DenoIsolate {
public:
- DenoIsolate(deno_buf snapshot, deno_config config)
+ DenoIsolate(deno_config config)
: isolate_(nullptr),
shared_(config.shared),
current_args_(nullptr),
@@ -23,9 +23,10 @@ class DenoIsolate {
next_req_id_(0),
user_data_(nullptr) {
array_buffer_allocator_ = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
- if (snapshot.data_ptr) {
- snapshot_.data = reinterpret_cast<const char*>(snapshot.data_ptr);
- snapshot_.raw_size = static_cast<int>(snapshot.data_len);
+ 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);
}
}
@@ -98,8 +99,7 @@ static const deno_buf empty_buf = {nullptr, 0, nullptr, 0};
Deno* NewFromSnapshot(void* user_data, deno_recv_cb cb);
-void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
- const char* js_filename, const char* js_source);
+void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context);
void HandleException(v8::Local<v8::Context> context,
v8::Local<v8::Value> exception);
diff --git a/libdeno/libdeno_test.cc b/libdeno/libdeno_test.cc
index 33a4702ae..9627f4a8d 100644
--- a/libdeno/libdeno_test.cc
+++ b/libdeno/libdeno_test.cc
@@ -3,30 +3,29 @@
TEST(LibDenoTest, InitializesCorrectly) {
EXPECT_NE(snapshot.data_ptr, nullptr);
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "1 + 2"));
deno_delete(d);
}
TEST(LibDenoTest, InitializesCorrectlyWithoutSnapshot) {
- Deno* d = deno_new(empty, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, empty, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "1 + 2"));
deno_delete(d);
}
TEST(LibDenoTest, SnapshotterInitializesCorrectly) {
- Deno* d =
- deno_new_snapshotter(deno_config{empty, nullptr}, "a.js", "a = 1 + 2");
+ Deno* d = deno_new(deno_config{1, empty, empty, nullptr});
deno_delete(d);
}
TEST(LibDenoTest, Snapshotter) {
- Deno* d1 =
- deno_new_snapshotter(deno_config{empty, nullptr}, "a.js", "a = 1 + 2");
+ Deno* d1 = deno_new(deno_config{1, empty, empty, nullptr});
+ EXPECT_TRUE(deno_execute(d1, nullptr, "a.js", "a = 1 + 2"));
deno_buf test_snapshot = deno_get_snapshot(d1);
deno_delete(d1);
- Deno* d2 = deno_new(test_snapshot, deno_config{empty, nullptr});
+ Deno* d2 = deno_new(deno_config{0, test_snapshot, empty, nullptr});
EXPECT_TRUE(
deno_execute(d2, nullptr, "b.js", "if (a != 3) throw Error('x');"));
deno_delete(d2);
@@ -35,14 +34,14 @@ TEST(LibDenoTest, Snapshotter) {
}
TEST(LibDenoTest, CanCallFunction) {
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js",
"if (CanCallFunction() != 'foo') throw Error();"));
deno_delete(d);
}
TEST(LibDenoTest, ErrorsCorrectly) {
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "throw Error()"));
deno_delete(d);
}
@@ -87,7 +86,7 @@ TEST(LibDenoTest, RecvReturnEmpty) {
EXPECT_EQ(buf.data_ptr[1], 'b');
EXPECT_EQ(buf.data_ptr[2], 'c');
};
- Deno* d = deno_new(snapshot, deno_config{empty, recv_cb});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "RecvReturnEmpty()"));
EXPECT_EQ(count, 2);
deno_delete(d);
@@ -105,14 +104,14 @@ TEST(LibDenoTest, RecvReturnBar) {
EXPECT_EQ(buf.data_ptr[2], 'c');
deno_respond(d, user_data, req_id, strbuf("bar"));
};
- Deno* d = deno_new(snapshot, deno_config{empty, recv_cb});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, d, "a.js", "RecvReturnBar()"));
EXPECT_EQ(count, 1);
deno_delete(d);
}
TEST(LibDenoTest, DoubleRecvFails) {
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "DoubleRecvFails()"));
deno_delete(d);
}
@@ -146,7 +145,7 @@ TEST(LibDenoTest, SendRecvSlice) {
// Send back.
deno_respond(d, user_data, req_id, buf2);
};
- Deno* d = deno_new(snapshot, deno_config{empty, recv_cb});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, d, "a.js", "SendRecvSlice()"));
EXPECT_EQ(count, 5);
deno_delete(d);
@@ -163,26 +162,26 @@ TEST(LibDenoTest, JSSendArrayBufferViewTypes) {
EXPECT_EQ(buf.alloc_len, 4321u);
EXPECT_EQ(buf.data_ptr[0], count);
};
- Deno* d = deno_new(snapshot, deno_config{empty, recv_cb});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "JSSendArrayBufferViewTypes()"));
EXPECT_EQ(count, 3);
deno_delete(d);
}
TEST(LibDenoTest, TypedArraySnapshots) {
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "TypedArraySnapshots()"));
deno_delete(d);
}
TEST(LibDenoTest, SnapshotBug) {
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "SnapshotBug()"));
deno_delete(d);
}
TEST(LibDenoTest, GlobalErrorHandling) {
- Deno* d = deno_new(snapshot, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr});
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "GlobalErrorHandling()"));
// We only check that it starts with this string, so we don't have to check
// the second frame, which contains line numbers in libdeno_test.js and may
@@ -210,7 +209,7 @@ TEST(LibDenoTest, DataBuf) {
EXPECT_EQ(buf.data_ptr[0], 1);
EXPECT_EQ(buf.data_ptr[1], 2);
};
- Deno* d = deno_new(snapshot, deno_config{empty, recv_cb});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "DataBuf()"));
EXPECT_EQ(count, 1);
// data_buf was subsequently changed in JS, let's check that our copy reflects
@@ -223,7 +222,7 @@ TEST(LibDenoTest, DataBuf) {
TEST(LibDenoTest, CheckPromiseErrors) {
static int count = 0;
auto recv_cb = [](auto _, int req_id, auto buf, auto data_buf) { count++; };
- Deno* d = deno_new(snapshot, deno_config{empty, recv_cb});
+ Deno* d = deno_new(deno_config{0, snapshot, empty, recv_cb});
EXPECT_EQ(deno_last_exception(d), nullptr);
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "CheckPromiseErrors()"));
EXPECT_EQ(deno_last_exception(d), nullptr);
@@ -236,7 +235,7 @@ TEST(LibDenoTest, CheckPromiseErrors) {
}
TEST(LibDenoTest, LastException) {
- Deno* d = deno_new(empty, deno_config{empty, nullptr});
+ Deno* d = deno_new(deno_config{0, empty, empty, nullptr});
EXPECT_EQ(deno_last_exception(d), nullptr);
EXPECT_FALSE(deno_execute(d, nullptr, "a.js", "\n\nthrow Error('boo');\n\n"));
EXPECT_STREQ(deno_last_exception(d),
@@ -251,7 +250,7 @@ TEST(LibDenoTest, LastException) {
TEST(LibDenoTest, Shared) {
uint8_t s[] = {0, 1, 2};
deno_buf shared = {nullptr, 0, s, 3};
- Deno* d = deno_new(snapshot, deno_config{shared, nullptr});
+ Deno* d = deno_new(deno_config{0, snapshot, shared, nullptr});
EXPECT_TRUE(deno_execute(d, nullptr, "a.js", "Shared()"));
EXPECT_EQ(s[0], 42);
EXPECT_EQ(s[1], 43);
diff --git a/libdeno/snapshot_creator.cc b/libdeno/snapshot_creator.cc
index 7e29b61c8..ba926d3f3 100644
--- a/libdeno/snapshot_creator.cc
+++ b/libdeno/snapshot_creator.cc
@@ -1,6 +1,7 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
// Hint: --trace_serializer is a useful debugging flag.
#include <fstream>
+#include <iostream>
#include "deno.h"
#include "file_util.h"
#include "internal.h"
@@ -22,8 +23,16 @@ int main(int argc, char** argv) {
CHECK(deno::ReadFileToString(js_fn, &js_source));
deno_init();
- deno_config config = {deno::empty_buf, nullptr};
- Deno* d = deno_new_snapshotter(config, js_fn, js_source.c_str());
+ deno_config config = {1, deno::empty_buf, deno::empty_buf, nullptr};
+ Deno* d = deno_new(config);
+
+ int r = deno_execute(d, nullptr, js_fn, js_source.c_str());
+ if (!r) {
+ std::cerr << "Snapshot Exception " << std::endl;
+ std::cerr << deno_last_exception(d) << std::endl;
+ deno_delete(d);
+ return 1;
+ }
auto snapshot = deno_get_snapshot(d);
diff --git a/src/isolate.rs b/src/isolate.rs
index 99e3670f2..2305a62a9 100644
--- a/src/isolate.rs
+++ b/src/isolate.rs
@@ -144,10 +144,12 @@ impl Isolate {
unsafe { libdeno::deno_init() };
});
let config = libdeno::deno_config {
+ will_snapshot: 0,
+ load_snapshot: snapshot,
shared: libdeno::deno_buf::empty(), // TODO Use for message passing.
recv_cb: pre_dispatch,
};
- let libdeno_isolate = unsafe { libdeno::deno_new(snapshot, config) };
+ let libdeno_isolate = unsafe { libdeno::deno_new(config) };
// This channel handles sending async messages back to the runtime.
let (tx, rx) = mpsc::channel::<(i32, Buf)>();
diff --git a/src/libdeno.rs b/src/libdeno.rs
index cbc074f1b..cce6c4e60 100644
--- a/src/libdeno.rs
+++ b/src/libdeno.rs
@@ -111,6 +111,8 @@ type DenoRecvCb = unsafe extern "C" fn(
#[repr(C)]
pub struct deno_config {
+ pub will_snapshot: c_int,
+ pub load_snapshot: deno_buf,
pub shared: deno_buf,
pub recv_cb: DenoRecvCb,
}
@@ -119,7 +121,7 @@ extern "C" {
pub fn deno_init();
pub fn deno_v8_version() -> *const c_char;
pub fn deno_set_v8_flags(argc: *mut c_int, argv: *mut *mut c_char);
- pub fn deno_new(snapshot: deno_buf, config: deno_config) -> *const isolate;
+ pub fn deno_new(config: deno_config) -> *const isolate;
pub fn deno_delete(i: *const isolate);
pub fn deno_last_exception(i: *const isolate) -> *const c_char;
pub fn deno_check_promise_errors(i: *const isolate);