mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
Use C linkage in deno.h
This commit is contained in:
parent
a6880dad65
commit
9296b21b87
6 changed files with 130 additions and 110 deletions
155
deno2/deno.cc
155
deno2/deno.cc
|
@ -28,7 +28,7 @@ IN THE SOFTWARE.
|
||||||
#include "v8/include/libplatform/libplatform.h"
|
#include "v8/include/libplatform/libplatform.h"
|
||||||
#include "v8/include/v8.h"
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
#include "deno_internal.h"
|
#include "./deno_internal.h"
|
||||||
#include "include/deno.h"
|
#include "include/deno.h"
|
||||||
|
|
||||||
#define CHECK(x) assert(x) // TODO(ry) use V8's CHECK.
|
#define CHECK(x) assert(x) // TODO(ry) use V8's CHECK.
|
||||||
|
@ -145,7 +145,7 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
void* buf = contents.Data();
|
void* buf = contents.Data();
|
||||||
int buflen = static_cast<int>(contents.ByteLength());
|
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) {
|
if (retbuf.data) {
|
||||||
auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.data, retbuf.len,
|
auto ab = v8::ArrayBuffer::New(d->isolate, retbuf.data, retbuf.len,
|
||||||
v8::ArrayBufferCreationMode::kInternalized);
|
v8::ArrayBufferCreationMode::kInternalized);
|
||||||
|
@ -161,15 +161,7 @@ void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* v8_version() { return v8::V8::GetVersion(); }
|
bool Load(v8::Local<v8::Context> context, const char* name_s,
|
||||||
|
|
||||||
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,
|
|
||||||
const char* source_s) {
|
const char* source_s) {
|
||||||
auto isolate = context->GetIsolate();
|
auto isolate = context->GetIsolate();
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
v8::Isolate::Scope isolate_scope(isolate);
|
||||||
|
@ -205,18 +197,91 @@ bool load(v8::Local<v8::Context> context, const char* name_s,
|
||||||
return true;
|
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) {
|
int deno_load(Deno* d, const char* name_s, const char* source_s) {
|
||||||
auto isolate = d->isolate;
|
auto isolate = d->isolate;
|
||||||
v8::Locker locker(isolate);
|
v8::Locker locker(isolate);
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
v8::Isolate::Scope isolate_scope(isolate);
|
||||||
v8::HandleScope handle_scope(isolate);
|
v8::HandleScope handle_scope(isolate);
|
||||||
auto context = d->context.Get(d->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.
|
// Called from golang. Must route message to javascript lang.
|
||||||
// non-zero return value indicates error. check deno_last_exception().
|
// 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::Locker locker(d->isolate);
|
||||||
v8::Isolate::Scope isolate_scope(d->isolate);
|
v8::Isolate::Scope isolate_scope(d->isolate);
|
||||||
v8::HandleScope handle_scope(d->isolate);
|
v8::HandleScope handle_scope(d->isolate);
|
||||||
|
@ -242,73 +307,13 @@ int deno_send(Deno* d, DenoBuf buf) {
|
||||||
recv->Call(context->Global(), 1, args);
|
recv->Call(context->Global(), 1, args);
|
||||||
|
|
||||||
if (try_catch.HasCaught()) {
|
if (try_catch.HasCaught()) {
|
||||||
HandleException(context, try_catch.Exception());
|
deno::HandleException(context, try_catch.Exception());
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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) {
|
void deno_dispose(Deno* d) {
|
||||||
d->isolate->Dispose();
|
d->isolate->Dispose();
|
||||||
delete (d);
|
delete (d);
|
||||||
|
@ -316,4 +321,4 @@ void deno_dispose(Deno* d) {
|
||||||
|
|
||||||
void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); }
|
void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); }
|
||||||
|
|
||||||
} // namespace deno
|
} // extern "C"
|
||||||
|
|
|
@ -7,18 +7,7 @@
|
||||||
#include "include/deno.h"
|
#include "include/deno.h"
|
||||||
#include "v8/include/v8.h"
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
namespace deno {
|
extern "C" {
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// deno_s = Wrapped Isolate.
|
// deno_s = Wrapped Isolate.
|
||||||
struct deno_s {
|
struct deno_s {
|
||||||
|
@ -29,8 +18,24 @@ struct deno_s {
|
||||||
RecvCallback cb;
|
RecvCallback cb;
|
||||||
void* data;
|
void* data;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void deno_add_isolate(Deno* d, v8::Isolate* isolate);
|
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 AddIsolate(Deno* d, v8::Isolate* isolate);
|
||||||
|
|
||||||
} // namespace deno
|
} // namespace deno
|
||||||
#endif // DENO_INTERNAL_H_
|
#endif // DENO_INTERNAL_H_
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace deno {
|
||||||
#include "natives_deno.cc"
|
#include "natives_deno.cc"
|
||||||
#include "snapshot_deno.cc"
|
#include "snapshot_deno.cc"
|
||||||
|
|
||||||
Deno* from_snapshot(void* data, RecvCallback cb) {
|
Deno* NewFromSnapshot(void* data, RecvCallback cb) {
|
||||||
auto natives_blob = *StartupBlob_natives();
|
auto natives_blob = *StartupBlob_natives();
|
||||||
printf("natives_blob %d bytes\n", natives_blob.raw_size);
|
printf("natives_blob %d bytes\n", natives_blob.raw_size);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ Deno* from_snapshot(void* data, RecvCallback cb) {
|
||||||
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||||
params.external_references = external_references;
|
params.external_references = external_references;
|
||||||
v8::Isolate* isolate = v8::Isolate::New(params);
|
v8::Isolate* isolate = v8::Isolate::New(params);
|
||||||
deno_add_isolate(d, isolate);
|
AddIsolate(d, isolate);
|
||||||
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
v8::Isolate::Scope isolate_scope(isolate);
|
||||||
{
|
{
|
||||||
|
@ -48,3 +48,10 @@ Deno* from_snapshot(void* data, RecvCallback cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace deno
|
} // namespace deno
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
Deno* deno_new(void* data, RecvCallback cb) {
|
||||||
|
return deno::NewFromSnapshot(data, cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,28 +2,30 @@
|
||||||
// All rights reserved. MIT License.
|
// All rights reserved. MIT License.
|
||||||
#ifndef INCLUDE_DENO_H_
|
#ifndef INCLUDE_DENO_H_
|
||||||
#define INCLUDE_DENO_H_
|
#define INCLUDE_DENO_H_
|
||||||
|
// Neither Rust nor Go support calling directly into C++ functions, therefore
|
||||||
namespace deno {
|
// the public interface to libdeno is done in C.
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
// Data that gets transmitted.
|
// Data that gets transmitted.
|
||||||
struct buf_s {
|
typedef struct {
|
||||||
void* data;
|
void* data;
|
||||||
size_t len;
|
size_t len;
|
||||||
};
|
} deno_buf;
|
||||||
typedef struct buf_s DenoBuf;
|
|
||||||
|
|
||||||
struct deno_s;
|
struct deno_s;
|
||||||
typedef struct deno_s Deno;
|
typedef struct deno_s Deno;
|
||||||
|
|
||||||
// The callback from V8 when data is sent.
|
// 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();
|
const char* v8_version();
|
||||||
void v8_set_flags(int* argc, char** argv);
|
void v8_set_flags(int* argc, char** argv);
|
||||||
|
|
||||||
// Constructors:
|
// Constructor
|
||||||
Deno* from_snapshot(void* data, RecvCallback cb);
|
Deno* deno_new(void* data, RecvCallback cb);
|
||||||
|
|
||||||
void* deno_get_data();
|
void* deno_get_data();
|
||||||
|
|
||||||
|
@ -32,13 +34,14 @@ void* deno_get_data();
|
||||||
int deno_load(Deno* d, const char* name_s, const char* source_s);
|
int deno_load(Deno* d, const char* name_s, const char* source_s);
|
||||||
|
|
||||||
// Returns nonzero on error.
|
// 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);
|
const char* deno_last_exception(Deno* d);
|
||||||
|
|
||||||
void deno_dispose(Deno* d);
|
void deno_dispose(Deno* d);
|
||||||
void deno_terminate_execution(Deno* d);
|
void deno_terminate_execution(Deno* d);
|
||||||
|
|
||||||
} // namespace deno
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
#endif // INCLUDE_DENO_H_
|
#endif // INCLUDE_DENO_H_
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
#include "include/deno.h"
|
#include "include/deno.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
deno::v8_init();
|
deno_init();
|
||||||
|
|
||||||
deno::Deno* d = deno::from_snapshot(NULL, NULL);
|
Deno* d = deno_new(NULL, NULL);
|
||||||
int r = deno::deno_load(d, "main2.js", "foo();");
|
int r = deno_load(d, "main2.js", "foo();");
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
printf("Error! %s\n", deno::deno_last_exception(d));
|
printf("Error! %s\n", deno_last_exception(d));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
#include "v8/include/v8.h"
|
#include "v8/include/v8.h"
|
||||||
|
|
||||||
#include "include/deno.h"
|
|
||||||
#include "./deno_internal.h"
|
#include "./deno_internal.h"
|
||||||
|
#include "include/deno.h"
|
||||||
|
|
||||||
class StartupDataCppWriter {
|
class StartupDataCppWriter {
|
||||||
public:
|
public:
|
||||||
|
@ -130,9 +130,9 @@ int main(int argc, char** argv) {
|
||||||
auto natives_blob = ReadFile(natives_in_bin);
|
auto natives_blob = ReadFile(natives_in_bin);
|
||||||
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
|
auto snapshot_in_blob = ReadFile(snapshot_in_bin);
|
||||||
|
|
||||||
deno::v8_init();
|
deno_init();
|
||||||
auto snapshot_blob = deno::make_snapshot(&natives_blob, &snapshot_in_blob,
|
auto snapshot_blob =
|
||||||
js_fn, js_data.data);
|
deno::MakeSnapshot(&natives_blob, &snapshot_in_blob, js_fn, js_data.data);
|
||||||
|
|
||||||
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
|
StartupDataCppWriter nativesWriter("natives", natives_out_cc, natives_blob);
|
||||||
nativesWriter.Write();
|
nativesWriter.Write();
|
||||||
|
|
Loading…
Reference in a new issue