diff options
author | Kevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com> | 2019-02-09 13:55:40 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-02-09 16:55:40 -0500 |
commit | 1d36eb47eb882cb9305a6338019fa2a2b375d7b1 (patch) | |
tree | 4584aff9da784f3e05c4fb5314d5911772b4d655 /libdeno/binding.cc | |
parent | 1502051453bf16787a59f43004b24d553d39bd26 (diff) |
Support scoped variables, unblock REPL async op, and REPL error colors (#1721)
Diffstat (limited to 'libdeno/binding.cc')
-rw-r--r-- | libdeno/binding.cc | 96 |
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()); |