summaryrefslogtreecommitdiff
path: root/libdeno/binding.cc
diff options
context:
space:
mode:
authorBert Belder <bertbelder@gmail.com>2018-10-07 23:48:06 +0200
committerBert Belder <bertbelder@gmail.com>2018-10-08 18:19:32 +0200
commite742af10aa67dc90a68fcb60b8e70733fd753e68 (patch)
treebc9d7360c5a8cb94e93f9dabf5749b94addc0c18 /libdeno/binding.cc
parentd86e5d2605c68606c8073d1b563d3389ea93c112 (diff)
Abide by the rules when passing Isolate between c and rust
Ensure that at most one mutable Isolate reference exists at a time. `deno_execute()` and `deno_respond()` now borrow a reference to the rust-side isolate from the caller. When we need a reference to the isolate while one of these functions is on the stack, `deno_get_data()` can be used to borrow back that reference.
Diffstat (limited to 'libdeno/binding.cc')
-rw-r--r--libdeno/binding.cc31
1 files changed, 27 insertions, 4 deletions
diff --git a/libdeno/binding.cc b/libdeno/binding.cc
index 7bc1a0397..55a78069e 100644
--- a/libdeno/binding.cc
+++ b/libdeno/binding.cc
@@ -401,6 +401,24 @@ void AddIsolate(Deno* d, v8::Isolate* isolate) {
d->isolate->SetData(0, d);
}
+class UserDataScope {
+ Deno* deno;
+ void* prev_data;
+ void* data; // Not necessary; only for sanity checking.
+
+ public:
+ UserDataScope(Deno* deno_, void* data_) : deno(deno_), data(data_) {
+ CHECK(deno->user_data == nullptr || deno->user_data == data_);
+ prev_data = deno->user_data;
+ deno->user_data = data;
+ }
+
+ ~UserDataScope() {
+ CHECK(deno->user_data == data);
+ deno->user_data = prev_data;
+ }
+};
+
} // namespace deno
extern "C" {
@@ -413,7 +431,10 @@ void deno_init() {
v8::V8::Initialize();
}
-void* deno_get_data(Deno* d) { return d->user_data; }
+void* deno_get_data(const Deno* d) {
+ CHECK(d->user_data != nullptr);
+ return d->user_data;
+}
const char* deno_v8_version() { return v8::V8::GetVersion(); }
@@ -423,7 +444,9 @@ void deno_set_v8_flags(int* argc, char** argv) {
const char* deno_last_exception(Deno* d) { return d->last_exception.c_str(); }
-int deno_execute(Deno* d, const char* js_filename, const char* js_source) {
+int deno_execute(Deno* d, void* user_data, const char* js_filename,
+ const char* js_source) {
+ deno::UserDataScope user_data_scope(d, user_data);
auto* isolate = d->isolate;
v8::Locker locker(isolate);
v8::Isolate::Scope isolate_scope(isolate);
@@ -432,7 +455,7 @@ int deno_execute(Deno* d, const char* js_filename, const char* js_source) {
return deno::Execute(context, js_filename, js_source) ? 1 : 0;
}
-int deno_respond(Deno* d, int32_t req_id, deno_buf buf) {
+int deno_respond(Deno* d, void* user_data, int32_t req_id, deno_buf buf) {
if (d->currentArgs != nullptr) {
// Synchronous response.
auto ab = deno::ImportBuf(d->isolate, buf);
@@ -442,7 +465,7 @@ int deno_respond(Deno* d, int32_t req_id, deno_buf buf) {
}
// Asynchronous response.
-
+ deno::UserDataScope user_data_scope(d, user_data);
v8::Locker locker(d->isolate);
v8::Isolate::Scope isolate_scope(d->isolate);
v8::HandleScope handle_scope(d->isolate);