Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #248

Closed
wants to merge 15 commits into from
Prev Previous commit
Next Next commit
Use C linkage in deno.h
  • Loading branch information
ry committed Jun 10, 2018
commit 9296b21b87eec3f01bee465fcb2b64c4ea14514b
155 changes: 80 additions & 75 deletions deno2/deno.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ IN THE SOFTWARE.
#include "v8/include/libplatform/libplatform.h"
#include "v8/include/v8.h"

#include "deno_internal.h"
#include "./deno_internal.h"
#include "include/deno.h"

#define CHECK(x) assert(x) // TODO(ry) use V8's CHECK.
Expand Down Expand Up @@ -145,7 +145,7 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
void* buf = contents.Data();
int buflen = static_cast<int>(contents.ByteLength());

auto retbuf = d->cb(d, DenoBuf{buf, buflen});
auto retbuf = d->cb(d, deno_buf{buf, buflen});
if (retbuf.data) {
auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.data, retbuf.len,
v8::ArrayBufferCreationMode::kInternalized);
Expand All @@ -161,15 +161,7 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
}

const char* v8_version() { return v8::V8::GetVersion(); }

void v8_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(); }

bool load(v8::Local<v8::Context> context, const char* name_s,
bool Load(v8::Local<v8::Context> context, const char* name_s,
const char* source_s) {
auto isolate = context->GetIsolate();
v8::Isolate::Scope isolate_scope(isolate);
Expand Down Expand Up @@ -205,18 +197,91 @@ bool load(v8::Local<v8::Context> context, const char* name_s,
return true;
}

v8::StartupData MakeSnapshot(v8::StartupData* prev_natives_blob,
v8::StartupData* prev_snapshot_blob,
const char* js_filename, const char* js_source) {
v8::V8::SetNativesDataBlob(prev_natives_blob);
v8::V8::SetSnapshotDataBlob(prev_snapshot_blob);

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);
v8::Context::Scope context_scope(context);

auto global = context->Global();

auto print_tmpl = v8::FunctionTemplate::New(isolate, Print);
auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
CHECK(
global->Set(context, deno::v8_str("deno_print"), print_val).FromJust());

auto recv_tmpl = v8::FunctionTemplate::New(isolate, Recv);
auto recv_val = recv_tmpl->GetFunction(context).ToLocalChecked();
CHECK(global->Set(context, deno::v8_str("deno_recv"), recv_val).FromJust());

auto send_tmpl = v8::FunctionTemplate::New(isolate, Send);
auto send_val = send_tmpl->GetFunction(context).ToLocalChecked();
CHECK(global->Set(context, deno::v8_str("deno_send"), send_val).FromJust());

bool r = Load(context, js_filename, js_source);
assert(r);

creator->SetDefaultContext(context);
}

auto snapshot_blob =
creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);

return snapshot_blob;
}

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();
}

const char* v8_version() { return v8::V8::GetVersion(); }

void v8_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_load(Deno* d, const char* name_s, const char* source_s) {
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 load(context, name_s, source_s) ? 0 : 1;
return deno::Load(context, name_s, source_s) ? 0 : 1;
}

// Called from golang. Must route message to javascript lang.
// non-zero return value indicates error. check deno_last_exception().
int deno_send(Deno* d, DenoBuf buf) {
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);
Expand All @@ -242,78 +307,18 @@ int deno_send(Deno* d, DenoBuf buf) {
recv->Call(context->Global(), 1, args);

if (try_catch.HasCaught()) {
HandleException(context, try_catch.Exception());
deno::HandleException(context, try_catch.Exception());
return 2;
}

return 0;
}

void v8_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_add_isolate(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(ExitOnPromiseRejectCallback);
d->isolate->SetData(0, d);
}

v8::StartupData make_snapshot(v8::StartupData* prev_natives_blob,
v8::StartupData* prev_snapshot_blob,
const char* js_filename, const char* js_source) {
v8::V8::SetNativesDataBlob(prev_natives_blob);
v8::V8::SetSnapshotDataBlob(prev_snapshot_blob);

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);
v8::Context::Scope context_scope(context);

auto global = context->Global();

auto print_tmpl = v8::FunctionTemplate::New(isolate, Print);
auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
CHECK(global->Set(context, v8_str("deno_print"), print_val).FromJust());

auto recv_tmpl = v8::FunctionTemplate::New(isolate, Recv);
auto recv_val = recv_tmpl->GetFunction(context).ToLocalChecked();
CHECK(global->Set(context, v8_str("deno_recv"), recv_val).FromJust());

auto send_tmpl = v8::FunctionTemplate::New(isolate, Send);
auto send_val = send_tmpl->GetFunction(context).ToLocalChecked();
CHECK(global->Set(context, v8_str("deno_send"), send_val).FromJust());

bool r = load(context, js_filename, js_source);
assert(r);

creator->SetDefaultContext(context);
}

auto snapshot_blob =
creator->CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);

return snapshot_blob;
}

void deno_dispose(Deno* d) {
d->isolate->Dispose();
delete (d);
}

void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); }

} // namespace deno
} // extern "C"
31 changes: 18 additions & 13 deletions deno2/deno_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,7 @@
#include "include/deno.h"
#include "v8/include/v8.h"

namespace deno {

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};

v8::StartupData make_snapshot(v8::StartupData* prev_natives_blob,
v8::StartupData* prev_snapshot_blob,
const char* js_filename, const char* js_source);
extern "C" {

// deno_s = Wrapped Isolate.
struct deno_s {
Expand All @@ -29,8 +18,24 @@ struct deno_s {
RecvCallback cb;
void* data;
};
}

namespace deno {

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, RecvCallback cb);

v8::StartupData MakeSnapshot(v8::StartupData* prev_natives_blob,
v8::StartupData* prev_snapshot_blob,
const char* js_filename, const char* js_source);

void deno_add_isolate(Deno* d, v8::Isolate* isolate);
void AddIsolate(Deno* d, v8::Isolate* isolate);

} // namespace deno
#endif // DENO_INTERNAL_H_
11 changes: 9 additions & 2 deletions deno2/from_snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace deno {
#include "natives_deno.cc"
#include "snapshot_deno.cc"

Deno* from_snapshot(void* data, RecvCallback cb) {
Deno* NewFromSnapshot(void* data, RecvCallback cb) {
auto natives_blob = *StartupBlob_natives();
printf("natives_blob %d bytes\n", natives_blob.raw_size);

Expand All @@ -35,7 +35,7 @@ Deno* from_snapshot(void* data, RecvCallback cb) {
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
params.external_references = external_references;
v8::Isolate* isolate = v8::Isolate::New(params);
deno_add_isolate(d, isolate);
AddIsolate(d, isolate);

v8::Isolate::Scope isolate_scope(isolate);
{
Expand All @@ -48,3 +48,10 @@ Deno* from_snapshot(void* data, RecvCallback cb) {
}

} // namespace deno

extern "C" {

Deno* deno_new(void* data, RecvCallback cb) {
return deno::NewFromSnapshot(data, cb);
}
}
27 changes: 15 additions & 12 deletions deno2/include/deno.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@
// All rights reserved. MIT License.
#ifndef INCLUDE_DENO_H_
#define INCLUDE_DENO_H_

namespace deno {
// 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.
struct buf_s {
typedef struct {
void* data;
size_t len;
};
typedef struct buf_s DenoBuf;
} deno_buf;

struct deno_s;
typedef struct deno_s Deno;

// The callback from V8 when data is sent.
typedef DenoBuf (*RecvCallback)(Deno* d, DenoBuf buf);
typedef deno_buf (*RecvCallback)(Deno* d, deno_buf buf);

void v8_init();
void deno_init();
const char* v8_version();
void v8_set_flags(int* argc, char** argv);

// Constructors:
Deno* from_snapshot(void* data, RecvCallback cb);
// Constructor
Deno* deno_new(void* data, RecvCallback cb);

void* deno_get_data();

Expand All @@ -32,13 +34,14 @@ void* deno_get_data();
int deno_load(Deno* d, const char* name_s, const char* source_s);

// Returns nonzero on error.
int deno_send(Deno* d, DenoBuf buf);
int deno_send(Deno* d, deno_buf buf);

const char* deno_last_exception(Deno* d);

void deno_dispose(Deno* d);
void deno_terminate_execution(Deno* d);

} // namespace deno

#ifdef __cplusplus
} // extern "C"
#endif
#endif // INCLUDE_DENO_H_
8 changes: 4 additions & 4 deletions deno2/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
#include "include/deno.h"

int main(int argc, char** argv) {
deno::v8_init();
deno_init();

deno::Deno* d = deno::from_snapshot(NULL, NULL);
int r = deno::deno_load(d, "main2.js", "foo();");
Deno* d = deno_new(NULL, NULL);
int r = deno_load(d, "main2.js", "foo();");
if (r != 0) {
printf("Error! %s\n", deno::deno_last_exception(d));
printf("Error! %s\n", deno_last_exception(d));
exit(1);
}
}
8 changes: 4 additions & 4 deletions deno2/snapshot_creator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

#include "v8/include/v8.h"

#include "include/deno.h"
#include "./deno_internal.h"
#include "include/deno.h"

class StartupDataCppWriter {
public:
Expand Down Expand Up @@ -130,9 +130,9 @@ int main(int argc, char** argv) {
auto natives_blob = ReadFile(natives_in_bin);
auto snapshot_in_blob = ReadFile(snapshot_in_bin);

deno::v8_init();
auto snapshot_blob = deno::make_snapshot(&natives_blob, &snapshot_in_blob,
js_fn, js_data.data);
deno_init();
auto snapshot_blob =
deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, js_fn, js_data.data);

StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
nativesWriter.Write();
Expand Down