summaryrefslogtreecommitdiff
path: root/libdeno/binding.cc
diff options
context:
space:
mode:
authorKevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com>2019-02-09 13:55:40 -0800
committerRyan Dahl <ry@tinyclouds.org>2019-02-09 16:55:40 -0500
commit1d36eb47eb882cb9305a6338019fa2a2b375d7b1 (patch)
tree4584aff9da784f3e05c4fb5314d5911772b4d655 /libdeno/binding.cc
parent1502051453bf16787a59f43004b24d553d39bd26 (diff)
Support scoped variables, unblock REPL async op, and REPL error colors (#1721)
Diffstat (limited to 'libdeno/binding.cc')
-rw-r--r--libdeno/binding.cc96
1 files changed, 96 insertions, 0 deletions
diff --git a/libdeno/binding.cc b/libdeno/binding.cc
index 78e4cad29..f7ee977e8 100644
--- a/libdeno/binding.cc
+++ b/libdeno/binding.cc
@@ -120,6 +120,16 @@ void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
fflush(file);
}
+void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ CHECK_EQ(args.Length(), 1);
+ auto* isolate = args.GetIsolate();
+ DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
+ auto context = d->context_.Get(d->isolate_);
+ v8::HandleScope handle_scope(isolate);
+ auto json_string = EncodeExceptionAsJSON(context, args[0]);
+ args.GetReturnValue().Set(v8_str(json_string.c_str()));
+}
+
v8::Local<v8::Uint8Array> ImportBuf(DenoIsolate* d, deno_buf buf) {
if (buf.alloc_ptr == nullptr) {
// If alloc_ptr isn't set, we memcpy.
@@ -368,6 +378,80 @@ bool Execute(v8::Local<v8::Context> context, const char* js_filename,
return true;
}
+static inline v8::Local<v8::Boolean> v8_bool(bool v) {
+ return v8::Boolean::New(v8::Isolate::GetCurrent(), v);
+}
+
+void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::Isolate* isolate = args.GetIsolate();
+ DenoIsolate* d = DenoIsolate::FromIsolate(isolate);
+ v8::EscapableHandleScope handleScope(isolate);
+ auto context = d->context_.Get(isolate);
+ v8::Context::Scope context_scope(context);
+
+ CHECK(args[0]->IsString());
+ auto source = args[0].As<v8::String>();
+
+ auto output = v8::Array::New(isolate, 2);
+ /**
+ * output[0] = result
+ * output[1] = ErrorInfo | null
+ * ErrorInfo = {
+ * thrown: Error | any,
+ * isNativeError: boolean,
+ * isCompileError: boolean,
+ * }
+ */
+
+ v8::TryCatch try_catch(isolate);
+
+ auto name = v8_str("<unknown>");
+ v8::ScriptOrigin origin(name);
+ auto script = v8::Script::Compile(context, source, &origin);
+
+ if (script.IsEmpty()) {
+ DCHECK(try_catch.HasCaught());
+ auto exception = try_catch.Exception();
+
+ output->Set(0, v8::Null(isolate));
+
+ auto errinfo_obj = v8::Object::New(isolate);
+ errinfo_obj->Set(v8_str("isCompileError"), v8_bool(true));
+ errinfo_obj->Set(v8_str("isNativeError"),
+ v8_bool(exception->IsNativeError()));
+ errinfo_obj->Set(v8_str("thrown"), exception);
+
+ output->Set(1, errinfo_obj);
+
+ args.GetReturnValue().Set(output);
+ return;
+ }
+
+ auto result = script.ToLocalChecked()->Run(context);
+
+ if (result.IsEmpty()) {
+ DCHECK(try_catch.HasCaught());
+ auto exception = try_catch.Exception();
+
+ output->Set(0, v8::Null(isolate));
+
+ auto errinfo_obj = v8::Object::New(isolate);
+ errinfo_obj->Set(v8_str("isCompileError"), v8_bool(false));
+ errinfo_obj->Set(v8_str("isNativeError"),
+ v8_bool(exception->IsNativeError()));
+ errinfo_obj->Set(v8_str("thrown"), exception);
+
+ output->Set(1, errinfo_obj);
+
+ args.GetReturnValue().Set(output);
+ return;
+ }
+
+ output->Set(0, result.ToLocalChecked());
+ output->Set(1, v8::Null(isolate));
+ args.GetReturnValue().Set(output);
+}
+
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
@@ -389,6 +473,18 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
auto send_val = send_tmpl->GetFunction(context).ToLocalChecked();
CHECK(deno_val->Set(context, deno::v8_str("send"), send_val).FromJust());
+ auto eval_context_tmpl = v8::FunctionTemplate::New(isolate, EvalContext);
+ auto eval_context_val =
+ eval_context_tmpl->GetFunction(context).ToLocalChecked();
+ CHECK(deno_val->Set(context, deno::v8_str("evalContext"), eval_context_val)
+ .FromJust());
+
+ auto error_to_json_tmpl = v8::FunctionTemplate::New(isolate, ErrorToJSON);
+ auto error_to_json_val =
+ error_to_json_tmpl->GetFunction(context).ToLocalChecked();
+ CHECK(deno_val->Set(context, deno::v8_str("errorToJSON"), error_to_json_val)
+ .FromJust());
+
CHECK(deno_val->SetAccessor(context, deno::v8_str("shared"), Shared)
.FromJust());