diff --git a/core/isolate.rs b/core/isolate.rs index b51b7fe47fe5f7..f277224d40acb4 100644 --- a/core/isolate.rs +++ b/core/isolate.rs @@ -340,6 +340,23 @@ impl Isolate { assert_ne!(snapshot.data_len, 0); Ok(snapshot) } + + pub fn set_op_id(&self, op_namespace: &str, op_name: &str, op_id: u32) { + let op_namespace_ = CString::new(op_namespace.to_string()).unwrap(); + let op_namespace_ptr = op_namespace_.as_ptr() as *const libc::c_char; + + let op_name_ = CString::new(op_name.to_string()).unwrap(); + let op_name_ptr = op_name_.as_ptr() as *const libc::c_char; + + unsafe { + libdeno::deno_set_op_id( + self.libdeno_isolate, + op_namespace_ptr, + op_name_ptr, + op_id as *const libc::c_int, + ) + } + } } /// Called during mod_instantiate() to resolve imports. diff --git a/core/libdeno.rs b/core/libdeno.rs index 046caaef655985..7e543a0d0584cc 100644 --- a/core/libdeno.rs +++ b/core/libdeno.rs @@ -292,6 +292,13 @@ extern "C" { id: deno_mod, ); + pub fn deno_set_op_id( + i: *const isolate, + op_namespace: *const c_char, + op_name: *const c_char, + op_id: *const c_int, + ); + pub fn deno_snapshot_new(i: *const isolate) -> Snapshot1<'static>; #[allow(dead_code)] diff --git a/core/libdeno/api.cc b/core/libdeno/api.cc index bcdf7131b75bc6..340424b2fa529d 100644 --- a/core/libdeno/api.cc +++ b/core/libdeno/api.cc @@ -243,4 +243,41 @@ void deno_terminate_execution(Deno* d_) { deno::DenoIsolate* d = reinterpret_cast(d_); d->isolate_->TerminateExecution(); } + +void deno_set_op_id(Deno* d_, const char* op_namespace, const char* op_name, + const int* op_id) { + auto* d = unwrap(d_); + + auto* isolate = d->isolate_; + v8::Isolate::Scope isolate_scope(isolate); + v8::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + auto context = d->context_.Get(d->isolate_); + v8::Context::Scope context_scope(context); + + v8::Local global = context->Global(); + + v8::Local deno_object = v8::Local::Cast( + global->Get(context, deno::v8_str("Deno")).ToLocalChecked()); + + v8::Local op_ids_object = v8::Local::Cast( + deno_object->Get(context, deno::v8_str("opIds")).ToLocalChecked()); + + if (op_ids_object->Has(context, deno::v8_str(op_namespace)).FromJust()) { + v8::Local op_ns_value = + op_ids_object->Get(context, deno::v8_str(op_namespace)) + .ToLocalChecked(); + auto op_ns_object = v8::Local::Cast(op_ns_value); + auto op_id_val = deno::v8_int(op_id); + CHECK(op_ns_object->Set(context, deno::v8_str(op_name), op_id_val) + .FromJust()); + } else { + auto op_ns_object = v8::Object::New(isolate); + auto op_id_val = deno::v8_int(op_id); + CHECK(op_ns_object->Set(context, deno::v8_str(op_name), op_id_val) + .FromJust()); + CHECK(op_ids_object->Set(context, deno::v8_str(op_namespace), op_ns_object) + .FromJust()); + } +} } diff --git a/core/libdeno/binding.cc b/core/libdeno/binding.cc index 8001534ff59193..0b40dfd56fb144 100644 --- a/core/libdeno/binding.cc +++ b/core/libdeno/binding.cc @@ -476,6 +476,9 @@ void InitializeContext(v8::Isolate* isolate, v8::Local context) { CHECK(core_val->SetAccessor(context, deno::v8_str("shared"), Shared) .FromJust()); + + auto op_ids_val = v8::Object::New(isolate); + CHECK(deno_val->Set(context, deno::v8_str("opIds"), op_ids_val).FromJust()); } void MessageCallback(v8::Local message, diff --git a/core/libdeno/deno.h b/core/libdeno/deno.h index f8bc9a82d47a8f..08e700339c6b2b 100644 --- a/core/libdeno/deno.h +++ b/core/libdeno/deno.h @@ -117,6 +117,9 @@ void deno_mod_instantiate(Deno* d, void* user_data, deno_mod id, // If it succeeded deno_last_exception() will return NULL. void deno_mod_evaluate(Deno* d, void* user_data, deno_mod id); +void deno_set_op_id(Deno* d, const char* op_namespace, const char* op_name, + const int* op_id); + #ifdef __cplusplus } // extern "C" #endif diff --git a/core/libdeno/internal.h b/core/libdeno/internal.h index 5e0051a8a6544b..dd0b663fffb3c1 100644 --- a/core/libdeno/internal.h +++ b/core/libdeno/internal.h @@ -139,6 +139,10 @@ static inline v8::Local v8_str(const char* x) { .ToLocalChecked(); } +static inline v8::Local v8_int(const int* x) { + return v8::Integer::New(v8::Isolate::GetCurrent(), *x); +} + void Print(const v8::FunctionCallbackInfo& args); void Recv(const v8::FunctionCallbackInfo& args); void Send(const v8::FunctionCallbackInfo& args); diff --git a/core/libdeno/libdeno_test.cc b/core/libdeno/libdeno_test.cc index ad4240da5dc0e6..4221c0756fd705 100644 --- a/core/libdeno/libdeno_test.cc +++ b/core/libdeno/libdeno_test.cc @@ -247,3 +247,14 @@ TEST(LibDenoTest, SharedAtomics) { EXPECT_EQ(s[2], 2); deno_delete(d); } + +TEST(LibDenoTest, CheckOpId) { + Deno* d = deno_new(deno_config{0, snapshot, empty, nullptr}); + int test_op_id = 0; + deno_set_op_id(d, "testNamespace", "testOp", &test_op_id); + int test_op_2_id = 1; + deno_set_op_id(d, "testNamespace", "testOp2", &test_op_2_id); + deno_execute(d, nullptr, "a.js", "CheckOpId()"); + EXPECT_EQ(nullptr, deno_last_exception(d)); + deno_delete(d); +} diff --git a/core/libdeno/libdeno_test.js b/core/libdeno/libdeno_test.js index 156af1e471c6f6..545adf2334c250 100644 --- a/core/libdeno/libdeno_test.js +++ b/core/libdeno/libdeno_test.js @@ -195,3 +195,8 @@ global.LibDenoEvalContextError = () => { assert(!errInfo5.isCompileError); // is NOT a compilation error! (just eval) assert(errInfo5.thrown.message === "Unexpected end of input"); }; + +global.CheckOpId = () => { + assert(Deno.opIds.testNamespace.testOp === 0); + assert(Deno.opIds.testNamespace.testOp2 === 1); +};