2018-06-10 00:32:04 +02:00
|
|
|
/*
|
|
|
|
Copyright 2018 Ryan Dahl <ry@tinyclouds.org>. All rights reserved.
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to
|
|
|
|
deal in the Software without restriction, including without limitation the
|
|
|
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
sell copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <string>
|
|
|
|
|
2018-07-03 17:15:32 +09:00
|
|
|
#include "third_party/v8/include/libplatform/libplatform.h"
|
|
|
|
#include "third_party/v8/include/v8.h"
|
|
|
|
#include "third_party/v8/src/base/logging.h"
|
2018-06-10 00:32:04 +02:00
|
|
|
|
2018-07-06 15:19:19 +08:00
|
|
|
#include "deno.h"
|
2018-07-06 15:00:45 -04:00
|
|
|
#include "internal.h"
|
2018-06-10 00:32:04 +02:00
|
|
|
|
2018-06-10 02:24:34 +02:00
|
|
|
namespace deno {
|
|
|
|
|
2018-06-10 00:32:04 +02:00
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
2018-06-10 06:13:48 +02:00
|
|
|
void HandleException(v8::Local<v8::Context> context,
|
|
|
|
v8::Local<v8::Value> exception) {
|
2018-06-10 14:24:39 +02:00
|
|
|
auto* isolate = context->GetIsolate();
|
2018-07-05 17:33:20 -04:00
|
|
|
Deno* d = static_cast<Deno*>(isolate->GetData(0));
|
2018-06-10 06:13:48 +02:00
|
|
|
v8::HandleScope handle_scope(isolate);
|
2018-06-10 00:32:04 +02:00
|
|
|
v8::Context::Scope context_scope(context);
|
|
|
|
|
2018-06-10 06:13:48 +02:00
|
|
|
auto message = v8::Exception::CreateMessage(isolate, exception);
|
|
|
|
auto onerrorStr = v8::String::NewFromUtf8(isolate, "onerror");
|
2018-06-10 00:32:04 +02:00
|
|
|
auto onerror = context->Global()->Get(onerrorStr);
|
2018-07-05 17:33:20 -04:00
|
|
|
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());
|
2018-06-10 00:32:04 +02:00
|
|
|
|
|
|
|
if (onerror->IsFunction()) {
|
2018-07-05 17:33:20 -04:00
|
|
|
// window.onerror is set so we try to handle the exception in javascript.
|
2018-06-10 00:32:04 +02:00
|
|
|
auto func = v8::Local<v8::Function>::Cast(onerror);
|
|
|
|
v8::Local<v8::Value> args[5];
|
|
|
|
args[0] = exception->ToString();
|
|
|
|
args[1] = message->GetScriptResourceName();
|
2018-06-22 14:57:49 +02:00
|
|
|
args[2] = line;
|
|
|
|
args[3] = column;
|
2018-06-10 00:32:04 +02:00
|
|
|
args[4] = exception;
|
|
|
|
func->Call(context->Global(), 5, args);
|
|
|
|
/* message, source, lineno, colno, error */
|
2018-07-05 17:33:20 -04:00
|
|
|
} else 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();
|
|
|
|
char buf[512];
|
|
|
|
snprintf(buf, sizeof(buf), "%s %d:%d\n", ToCString(script_name), l, c);
|
|
|
|
msg += buf;
|
|
|
|
}
|
|
|
|
d->last_exception = msg;
|
2018-06-10 00:32:04 +02:00
|
|
|
} else {
|
2018-07-05 17:33:20 -04:00
|
|
|
// No javascript onerror handler, no stack trace. Format the little info we
|
|
|
|
// have into a string and add to last_exception.
|
2018-06-10 06:13:48 +02:00
|
|
|
v8::String::Utf8Value exceptionStr(isolate, exception);
|
2018-07-05 17:33:20 -04:00
|
|
|
v8::String::Utf8Value script_name(isolate,
|
|
|
|
message->GetScriptResourceName());
|
|
|
|
v8::String::Utf8Value line_str(isolate, line);
|
|
|
|
v8::String::Utf8Value col_str(isolate, column);
|
|
|
|
char buf[512];
|
|
|
|
snprintf(buf, sizeof(buf), "%s\n%s %s:%s\n", ToCString(exceptionStr),
|
|
|
|
ToCString(script_name), ToCString(line_str), ToCString(col_str));
|
|
|
|
d->last_exception = std::string(buf);
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
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));
|
2018-06-14 00:55:40 +02:00
|
|
|
DCHECK_EQ(d->isolate, isolate);
|
2018-06-10 00:32:04 +02:00
|
|
|
v8::HandleScope handle_scope(d->isolate);
|
|
|
|
auto exception = promise_reject_message.GetValue();
|
2018-06-10 06:13:48 +02:00
|
|
|
auto context = d->context.Get(d->isolate);
|
|
|
|
HandleException(context, exception);
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
2018-06-14 00:55:40 +02:00
|
|
|
CHECK_EQ(args.Length(), 1);
|
2018-06-10 00:32:04 +02:00
|
|
|
auto* isolate = args.GetIsolate();
|
2018-06-10 02:02:40 +02:00
|
|
|
v8::HandleScope handle_scope(isolate);
|
|
|
|
v8::String::Utf8Value str(isolate, args[0]);
|
|
|
|
const char* cstr = ToCString(str);
|
|
|
|
printf("%s\n", cstr);
|
2018-06-10 00:32:04 +02:00
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
2018-07-09 03:35:34 +02:00
|
|
|
static v8::Local<v8::Uint8Array> ImportBuf(v8::Isolate* isolate, deno_buf buf) {
|
|
|
|
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); }
|
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
// Sets the recv callback.
|
|
|
|
void Recv(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
2018-06-10 00:32:04 +02:00
|
|
|
v8::Isolate* isolate = args.GetIsolate();
|
|
|
|
Deno* d = reinterpret_cast<Deno*>(isolate->GetData(0));
|
2018-06-14 00:55:40 +02:00
|
|
|
DCHECK_EQ(d->isolate, isolate);
|
2018-06-10 00:32:04 +02:00
|
|
|
|
|
|
|
v8::HandleScope handle_scope(isolate);
|
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
if (!d->recv.IsEmpty()) {
|
|
|
|
isolate->ThrowException(v8_str("deno.recv already called."));
|
2018-06-11 22:51:11 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-10 00:32:04 +02:00
|
|
|
v8::Local<v8::Value> v = args[0];
|
2018-06-14 00:55:40 +02:00
|
|
|
CHECK(v->IsFunction());
|
2018-06-10 00:32:04 +02:00
|
|
|
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(v);
|
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
d->recv.Reset(isolate, func);
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
void Send(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
2018-06-10 00:32:04 +02:00
|
|
|
v8::Isolate* isolate = args.GetIsolate();
|
|
|
|
Deno* d = static_cast<Deno*>(isolate->GetData(0));
|
2018-06-14 00:55:40 +02:00
|
|
|
DCHECK_EQ(d->isolate, isolate);
|
2018-06-10 00:32:04 +02:00
|
|
|
|
|
|
|
v8::Locker locker(d->isolate);
|
|
|
|
v8::EscapableHandleScope handle_scope(isolate);
|
|
|
|
|
2018-07-06 16:26:34 -04:00
|
|
|
CHECK_EQ(args.Length(), 1);
|
|
|
|
v8::Local<v8::Value> ab_v = args[0];
|
2018-07-09 03:35:34 +02:00
|
|
|
CHECK(ab_v->IsArrayBufferView());
|
|
|
|
auto buf = ExportBuf(isolate, v8::Local<v8::ArrayBufferView>::Cast(ab_v));
|
2018-06-10 00:32:04 +02:00
|
|
|
|
2018-06-14 00:55:40 +02:00
|
|
|
DCHECK_EQ(d->currentArgs, nullptr);
|
2018-06-13 19:38:22 +02:00
|
|
|
d->currentArgs = &args;
|
|
|
|
|
2018-07-06 16:26:34 -04:00
|
|
|
d->cb(d, buf);
|
2018-06-13 19:38:22 +02:00
|
|
|
|
2018-07-09 03:35:34 +02:00
|
|
|
// 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);
|
|
|
|
|
2018-06-13 19:38:22 +02:00
|
|
|
d->currentArgs = nullptr;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-06-11 20:49:57 +02:00
|
|
|
bool Execute(v8::Local<v8::Context> context, const char* js_filename,
|
|
|
|
const char* js_source) {
|
2018-06-10 14:24:39 +02:00
|
|
|
auto* isolate = context->GetIsolate();
|
2018-06-10 06:13:48 +02:00
|
|
|
v8::Isolate::Scope isolate_scope(isolate);
|
|
|
|
v8::HandleScope handle_scope(isolate);
|
2018-06-10 00:32:04 +02:00
|
|
|
|
|
|
|
v8::Context::Scope context_scope(context);
|
|
|
|
|
2018-06-10 06:13:48 +02:00
|
|
|
v8::TryCatch try_catch(isolate);
|
2018-06-10 00:32:04 +02:00
|
|
|
|
2018-06-11 20:49:57 +02:00
|
|
|
auto name = v8_str(js_filename);
|
|
|
|
auto source = v8_str(js_source);
|
2018-06-10 00:32:04 +02:00
|
|
|
|
|
|
|
v8::ScriptOrigin origin(name);
|
|
|
|
|
|
|
|
auto script = v8::Script::Compile(context, source, &origin);
|
|
|
|
|
|
|
|
if (script.IsEmpty()) {
|
2018-06-14 00:55:40 +02:00
|
|
|
DCHECK(try_catch.HasCaught());
|
2018-06-10 06:13:48 +02:00
|
|
|
HandleException(context, try_catch.Exception());
|
|
|
|
return false;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
auto result = script.ToLocalChecked()->Run(context);
|
|
|
|
|
|
|
|
if (result.IsEmpty()) {
|
2018-06-14 00:55:40 +02:00
|
|
|
DCHECK(try_catch.HasCaught());
|
2018-06-10 06:13:48 +02:00
|
|
|
HandleException(context, try_catch.Exception());
|
|
|
|
return false;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-06-10 06:13:48 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-06-13 20:55:08 +02:00
|
|
|
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context,
|
|
|
|
const char* js_filename, const char* js_source) {
|
|
|
|
v8::HandleScope handle_scope(isolate);
|
|
|
|
v8::Context::Scope context_scope(context);
|
|
|
|
|
|
|
|
auto global = context->Global();
|
2018-06-14 14:31:31 +02:00
|
|
|
|
|
|
|
auto deno_val = v8::Object::New(isolate);
|
|
|
|
CHECK(global->Set(context, deno::v8_str("deno"), deno_val).FromJust());
|
|
|
|
|
2018-06-13 20:55:08 +02:00
|
|
|
auto print_tmpl = v8::FunctionTemplate::New(isolate, Print);
|
|
|
|
auto print_val = print_tmpl->GetFunction(context).ToLocalChecked();
|
2018-06-14 14:31:31 +02:00
|
|
|
CHECK(deno_val->Set(context, deno::v8_str("print"), print_val).FromJust());
|
2018-06-13 20:55:08 +02:00
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
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());
|
2018-06-13 20:55:08 +02:00
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
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());
|
2018-06-13 20:55:08 +02:00
|
|
|
|
|
|
|
bool r = Execute(context, js_filename, js_source);
|
|
|
|
CHECK(r);
|
|
|
|
}
|
|
|
|
|
2018-06-10 14:18:15 +02:00
|
|
|
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]);
|
2018-06-10 14:24:39 +02:00
|
|
|
auto* p = v8::platform::CreateDefaultPlatform();
|
2018-06-10 14:18:15 +02:00
|
|
|
v8::V8::InitializePlatform(p);
|
|
|
|
v8::V8::Initialize();
|
|
|
|
}
|
|
|
|
|
2018-06-10 14:34:59 +02:00
|
|
|
const char* deno_v8_version() { return v8::V8::GetVersion(); }
|
2018-06-10 14:18:15 +02:00
|
|
|
|
2018-07-13 03:24:07 -04:00
|
|
|
// TODO(ry) Remove these when we call deno_reply_start from Rust.
|
|
|
|
static char** global_argv;
|
|
|
|
static int global_argc;
|
|
|
|
char** deno_argv() { return global_argv; }
|
|
|
|
int deno_argc() { return global_argc; }
|
|
|
|
|
2018-06-10 14:34:59 +02:00
|
|
|
void deno_set_flags(int* argc, char** argv) {
|
2018-06-10 14:18:15 +02:00
|
|
|
v8::V8::SetFlagsFromCommandLine(argc, argv, true);
|
2018-07-13 03:24:07 -04:00
|
|
|
// TODO(ry) Remove these when we call deno_reply_start from Rust.
|
|
|
|
global_argc = *argc;
|
|
|
|
global_argv = reinterpret_cast<char**>(malloc(*argc * sizeof(char*)));
|
|
|
|
for (int i = 0; i < *argc; i++) {
|
|
|
|
global_argv[i] = strdup(argv[i]);
|
|
|
|
}
|
2018-06-10 14:18:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); }
|
|
|
|
|
2018-06-15 15:12:32 +02:00
|
|
|
int deno_execute(Deno* d, const char* js_filename, const char* js_source) {
|
2018-06-10 14:24:39 +02:00
|
|
|
auto* isolate = d->isolate;
|
2018-06-10 06:13:48 +02:00
|
|
|
v8::Locker locker(isolate);
|
|
|
|
v8::Isolate::Scope isolate_scope(isolate);
|
|
|
|
v8::HandleScope handle_scope(isolate);
|
|
|
|
auto context = d->context.Get(d->isolate);
|
2018-06-15 15:12:32 +02:00
|
|
|
return deno::Execute(context, js_filename, js_source) ? 1 : 0;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-07-06 16:26:34 -04:00
|
|
|
int deno_send(Deno* d, deno_buf buf) {
|
2018-06-10 00:32:04 +02:00
|
|
|
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);
|
|
|
|
|
2018-07-01 18:07:12 +02:00
|
|
|
auto recv = d->recv.Get(d->isolate);
|
|
|
|
if (recv.IsEmpty()) {
|
|
|
|
d->last_exception = "deno.recv has not been called.";
|
2018-06-15 15:12:32 +02:00
|
|
|
return 0;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-07-06 16:26:34 -04:00
|
|
|
v8::Local<v8::Value> args[1];
|
2018-07-09 03:35:34 +02:00
|
|
|
args[0] = deno::ImportBuf(d->isolate, buf);
|
2018-07-01 18:07:12 +02:00
|
|
|
recv->Call(context->Global(), 1, args);
|
2018-06-10 00:32:04 +02:00
|
|
|
|
|
|
|
if (try_catch.HasCaught()) {
|
2018-06-10 14:18:15 +02:00
|
|
|
deno::HandleException(context, try_catch.Exception());
|
2018-06-15 15:12:32 +02:00
|
|
|
return 0;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-06-15 15:12:32 +02:00
|
|
|
return 1;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
2018-06-13 19:38:22 +02:00
|
|
|
void deno_set_response(Deno* d, deno_buf buf) {
|
2018-07-09 03:35:34 +02:00
|
|
|
auto ab = deno::ImportBuf(d->isolate, buf);
|
2018-06-13 19:38:22 +02:00
|
|
|
d->currentArgs->GetReturnValue().Set(ab);
|
|
|
|
}
|
|
|
|
|
2018-06-11 22:36:14 +02:00
|
|
|
void deno_delete(Deno* d) {
|
2018-06-10 00:32:04 +02:00
|
|
|
d->isolate->Dispose();
|
2018-06-11 22:36:14 +02:00
|
|
|
delete d;
|
2018-06-10 00:32:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void deno_terminate_execution(Deno* d) { d->isolate->TerminateExecution(); }
|
2018-06-10 02:24:34 +02:00
|
|
|
|
2018-06-10 14:18:15 +02:00
|
|
|
} // extern "C"
|