summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdeno/api.cc29
-rw-r--r--libdeno/binding.cc25
-rw-r--r--libdeno/deno.h5
-rw-r--r--libdeno/internal.h12
-rw-r--r--libdeno/libdeno_test.cc11
-rw-r--r--libdeno/snapshot_creator.cc47
6 files changed, 82 insertions, 47 deletions
diff --git a/libdeno/api.cc b/libdeno/api.cc
index e01f95e82..512252737 100644
--- a/libdeno/api.cc
+++ b/libdeno/api.cc
@@ -42,10 +42,39 @@ Deno* deno_new(deno_buf snapshot, deno_recv_cb cb) {
return reinterpret_cast<Deno*>(d);
}
+Deno* deno_new_snapshotter(deno_recv_cb cb, const char* js_filename,
+ const char* js_source, const char* source_map) {
+ auto* creator = new v8::SnapshotCreator(deno::external_references);
+ auto* isolate = creator->GetIsolate();
+ auto* d = new deno::DenoIsolate(deno::empty_buf, cb);
+ d->snapshot_creator_ = creator;
+ d->AddIsolate(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,
+ source_map);
+ }
+ return reinterpret_cast<Deno*>(d);
+}
+
deno::DenoIsolate* unwrap(Deno* d_) {
return reinterpret_cast<deno::DenoIsolate*>(d_);
}
+deno_buf deno_get_snapshot(Deno* d_) {
+ auto* d = unwrap(d_);
+ CHECK_NE(d->snapshot_creator_, nullptr);
+ auto blob = d->snapshot_creator_->CreateBlob(
+ v8::SnapshotCreator::FunctionCodeHandling::kClear);
+ return {nullptr, 0, reinterpret_cast<uint8_t*>(const_cast<char*>(blob.data)),
+ blob.raw_size};
+}
+
void deno_init() {
// v8::V8::InitializeICUDefaultLocation(argv[0]);
// v8::V8::InitializeExternalStartupData(argv[0]);
diff --git a/libdeno/binding.cc b/libdeno/binding.cc
index 9fca3814c..686defffa 100644
--- a/libdeno/binding.cc
+++ b/libdeno/binding.cc
@@ -30,6 +30,19 @@ void DeserializeInternalFields(v8::Local<v8::Object> holder, int index,
deserialized_data.push_back(embedder_field);
}
+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};
+}
+
DenoIsolate* FromIsolate(v8::Isolate* isolate) {
return static_cast<DenoIsolate*>(isolate->GetData(0));
}
@@ -433,8 +446,10 @@ bool Execute(v8::Local<v8::Context> context, const char* js_filename,
}
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
- const char* js_filename, const std::string& js_source,
- const std::string* source_map) {
+ const char* js_filename, const char* js_source,
+ const char* source_map) {
+ CHECK_NE(js_source, nullptr);
+ CHECK_NE(js_filename, nullptr);
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
@@ -483,7 +498,7 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
.FromJust());
{
- auto source = deno::v8_str(js_source.c_str());
+ auto source = deno::v8_str(js_source);
CHECK(
deno_val->Set(context, deno::v8_str("mainSource"), source).FromJust());
@@ -491,10 +506,10 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
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 + ")";
+ std::string source_map_parens =
+ std::string("(") + std::string(source_map) + std::string(")");
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()) {
diff --git a/libdeno/deno.h b/libdeno/deno.h
index f833bd541..c29bfc0bb 100644
--- a/libdeno/deno.h
+++ b/libdeno/deno.h
@@ -30,6 +30,11 @@ const char* deno_v8_version();
void deno_set_v8_flags(int* argc, char** argv);
Deno* deno_new(deno_buf snapshot, deno_recv_cb cb);
+
+Deno* deno_new_snapshotter(deno_recv_cb cb, const char* js_filename,
+ const char* js_source, const char* source_map);
+deno_buf deno_get_snapshot(Deno* d);
+
void deno_delete(Deno* d);
// Returns false on error.
diff --git a/libdeno/internal.h b/libdeno/internal.h
index d71b36048..6816debec 100644
--- a/libdeno/internal.h
+++ b/libdeno/internal.h
@@ -16,6 +16,7 @@ class DenoIsolate {
DenoIsolate(deno_buf snapshot, deno_recv_cb cb)
: isolate_(nullptr),
current_args_(nullptr),
+ snapshot_creator_(nullptr),
global_import_buf_ptr_(nullptr),
pending_promise_events_(0),
cb_(cb),
@@ -30,8 +31,8 @@ class DenoIsolate {
void AddIsolate(v8::Isolate* isolate);
v8::Isolate* isolate_;
- // Put v8::Isolate::CreateParams here..
const v8::FunctionCallbackInfo<v8::Value>* current_args_;
+ v8::SnapshotCreator* snapshot_creator_;
void* global_import_buf_ptr_;
int32_t pending_promise_events_;
deno_recv_cb cb_;
@@ -86,11 +87,13 @@ static intptr_t external_references[] = {
reinterpret_cast<intptr_t>(SetPromiseErrorExaminer),
0};
+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 std::string& js_source,
- const std::string* source_map);
+ const char* js_filename, const char* js_source,
+ const char* source_map);
void HandleException(v8::Local<v8::Context> context,
v8::Local<v8::Value> exception);
@@ -98,6 +101,9 @@ void HandleException(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);
void DeleteDataRef(DenoIsolate* d, int32_t req_id);
diff --git a/libdeno/libdeno_test.cc b/libdeno/libdeno_test.cc
index 447012412..54285566f 100644
--- a/libdeno/libdeno_test.cc
+++ b/libdeno/libdeno_test.cc
@@ -16,6 +16,17 @@ TEST(LibDenoTest, InitializesCorrectlyWithoutSnapshot) {
deno_delete(d);
}
+TEST(LibDenoTest, Snapshotter) {
+ Deno* d1 = deno_new_snapshotter(nullptr, "a.js", "a = 1 + 2", nullptr);
+ deno_buf test_snapshot = deno_get_snapshot(d1);
+ // TODO(ry) deno_delete(d1);
+
+ Deno* d2 = deno_new(test_snapshot, nullptr);
+ EXPECT_TRUE(
+ deno_execute(d2, nullptr, "b.js", "if (a != 3) throw Error('x');"));
+ deno_delete(d2);
+}
+
TEST(LibDenoTest, CanCallFunction) {
Deno* d = deno_new(snapshot, nullptr);
EXPECT_TRUE(deno_execute(d, nullptr, "a.js",
diff --git a/libdeno/snapshot_creator.cc b/libdeno/snapshot_creator.cc
index 8038c9b13..e2511461b 100644
--- a/libdeno/snapshot_creator.cc
+++ b/libdeno/snapshot_creator.cc
@@ -7,42 +7,7 @@
#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
+namespace deno {} // namespace deno
int main(int argc, char** argv) {
const char* snapshot_out_bin = argv[1];
@@ -64,9 +29,13 @@ int main(int argc, char** argv) {
}
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);
+ Deno* d = deno_new_snapshotter(
+ nullptr, js_fn, js_source.c_str(),
+ source_map_fn != nullptr ? source_map.c_str() : nullptr);
+
+ auto snapshot = deno_get_snapshot(d);
+ std::string snapshot_str(reinterpret_cast<char*>(snapshot.data_ptr),
+ snapshot.data_len);
std::ofstream file_(snapshot_out_bin, std::ios::binary);
file_ << snapshot_str;