summaryrefslogtreecommitdiff
path: root/core/bindings.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-01-06 20:07:35 +0100
committerGitHub <noreply@github.com>2020-01-06 20:07:35 +0100
commit8bf383710fc32efdbf2996abf5130bbd9aecacd1 (patch)
tree240927ae043a9d3596b039e5762d8d078e738d04 /core/bindings.rs
parent29df272133425ed5d9c54a584c60193fb3ad6086 (diff)
refactor: remove core/libdeno.rs (#3611)
Diffstat (limited to 'core/bindings.rs')
-rw-r--r--core/bindings.rs294
1 files changed, 247 insertions, 47 deletions
diff --git a/core/bindings.rs b/core/bindings.rs
index 516bb5531..78777089b 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -1,22 +1,226 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#![allow(mutable_transmutes)]
-#![allow(clippy::transmute_ptr_to_ptr)]
-
+use crate::isolate::DenoBuf;
use crate::isolate::Isolate;
-use crate::libdeno::deno_buf;
-use crate::libdeno::script_origin;
-use crate::libdeno::PinnedBuf;
+use crate::isolate::PinnedBuf;
+use crate::isolate::ResolveContext;
use rusty_v8 as v8;
use v8::InIsolate;
-use libc::c_char;
use libc::c_void;
use std::convert::TryFrom;
-use std::ffi::CString;
use std::option::Option;
+lazy_static! {
+ pub static ref EXTERNAL_REFERENCES: v8::ExternalReferences =
+ v8::ExternalReferences::new(&[
+ v8::ExternalReference { function: print },
+ v8::ExternalReference { function: recv },
+ v8::ExternalReference { function: send },
+ v8::ExternalReference {
+ function: eval_context
+ },
+ v8::ExternalReference {
+ function: error_to_json
+ },
+ v8::ExternalReference {
+ getter: shared_getter
+ },
+ v8::ExternalReference {
+ message: message_callback
+ },
+ v8::ExternalReference {
+ function: queue_microtask
+ },
+ ]);
+}
+
+pub fn script_origin<'a>(
+ s: &mut impl v8::ToLocal<'a>,
+ resource_name: v8::Local<'a, v8::String>,
+) -> v8::ScriptOrigin<'a> {
+ let resource_line_offset = v8::Integer::new(s, 0);
+ let resource_column_offset = v8::Integer::new(s, 0);
+ let resource_is_shared_cross_origin = v8::Boolean::new(s, false);
+ let script_id = v8::Integer::new(s, 123);
+ let source_map_url = v8::String::new(s, "source_map_url").unwrap();
+ let resource_is_opaque = v8::Boolean::new(s, true);
+ let is_wasm = v8::Boolean::new(s, false);
+ let is_module = v8::Boolean::new(s, false);
+ v8::ScriptOrigin::new(
+ resource_name.into(),
+ resource_line_offset,
+ resource_column_offset,
+ resource_is_shared_cross_origin,
+ script_id,
+ source_map_url.into(),
+ resource_is_opaque,
+ is_wasm,
+ is_module,
+ )
+}
+
+pub fn module_origin<'a>(
+ s: &mut impl v8::ToLocal<'a>,
+ resource_name: v8::Local<'a, v8::String>,
+) -> v8::ScriptOrigin<'a> {
+ let resource_line_offset = v8::Integer::new(s, 0);
+ let resource_column_offset = v8::Integer::new(s, 0);
+ let resource_is_shared_cross_origin = v8::Boolean::new(s, false);
+ let script_id = v8::Integer::new(s, 123);
+ let source_map_url = v8::String::new(s, "source_map_url").unwrap();
+ let resource_is_opaque = v8::Boolean::new(s, true);
+ let is_wasm = v8::Boolean::new(s, false);
+ let is_module = v8::Boolean::new(s, true);
+ v8::ScriptOrigin::new(
+ resource_name.into(),
+ resource_line_offset,
+ resource_column_offset,
+ resource_is_shared_cross_origin,
+ script_id,
+ source_map_url.into(),
+ resource_is_opaque,
+ is_wasm,
+ is_module,
+ )
+}
+
+pub fn initialize_context<'a>(
+ scope: &mut impl v8::ToLocal<'a>,
+ mut context: v8::Local<v8::Context>,
+) {
+ context.enter();
+
+ let global = context.global(scope);
+
+ let deno_val = v8::Object::new(scope);
+
+ global.set(
+ context,
+ v8::String::new(scope, "Deno").unwrap().into(),
+ deno_val.into(),
+ );
+
+ let mut core_val = v8::Object::new(scope);
+
+ deno_val.set(
+ context,
+ v8::String::new(scope, "core").unwrap().into(),
+ core_val.into(),
+ );
+
+ let mut print_tmpl = v8::FunctionTemplate::new(scope, print);
+ let print_val = print_tmpl.get_function(scope, context).unwrap();
+ core_val.set(
+ context,
+ v8::String::new(scope, "print").unwrap().into(),
+ print_val.into(),
+ );
+
+ let mut recv_tmpl = v8::FunctionTemplate::new(scope, recv);
+ let recv_val = recv_tmpl.get_function(scope, context).unwrap();
+ core_val.set(
+ context,
+ v8::String::new(scope, "recv").unwrap().into(),
+ recv_val.into(),
+ );
+
+ let mut send_tmpl = v8::FunctionTemplate::new(scope, send);
+ let send_val = send_tmpl.get_function(scope, context).unwrap();
+ core_val.set(
+ context,
+ v8::String::new(scope, "send").unwrap().into(),
+ send_val.into(),
+ );
+
+ let mut eval_context_tmpl = v8::FunctionTemplate::new(scope, eval_context);
+ let eval_context_val =
+ eval_context_tmpl.get_function(scope, context).unwrap();
+ core_val.set(
+ context,
+ v8::String::new(scope, "evalContext").unwrap().into(),
+ eval_context_val.into(),
+ );
+
+ let mut error_to_json_tmpl = v8::FunctionTemplate::new(scope, error_to_json);
+ let error_to_json_val =
+ error_to_json_tmpl.get_function(scope, context).unwrap();
+ core_val.set(
+ context,
+ v8::String::new(scope, "errorToJSON").unwrap().into(),
+ error_to_json_val.into(),
+ );
+
+ core_val.set_accessor(
+ context,
+ v8::String::new(scope, "shared").unwrap().into(),
+ shared_getter,
+ );
+
+ // Direct bindings on `window`.
+ let mut queue_microtask_tmpl =
+ v8::FunctionTemplate::new(scope, queue_microtask);
+ let queue_microtask_val =
+ queue_microtask_tmpl.get_function(scope, context).unwrap();
+ global.set(
+ context,
+ v8::String::new(scope, "queueMicrotask").unwrap().into(),
+ queue_microtask_val.into(),
+ );
+
+ context.exit();
+}
+
+pub unsafe fn buf_to_uint8array<'sc>(
+ scope: &mut impl v8::ToLocal<'sc>,
+ buf: DenoBuf,
+) -> v8::Local<'sc, v8::Uint8Array> {
+ if buf.data_ptr.is_null() {
+ let ab = v8::ArrayBuffer::new(scope, 0);
+ return v8::Uint8Array::new(ab, 0, 0).expect("Failed to create UintArray8");
+ }
+
+ /*
+ // To avoid excessively allocating new ArrayBuffers, we try to reuse a single
+ // global ArrayBuffer. The caveat is that users must extract data from it
+ // before the next tick. We only do this for ArrayBuffers less than 1024
+ // bytes.
+ v8::Local<v8::ArrayBuffer> ab;
+ void* data;
+ if (buf.data_len > GLOBAL_IMPORT_BUF_SIZE) {
+ // Simple case. We allocate a new ArrayBuffer for this.
+ ab = v8::ArrayBuffer::New(d->isolate_, buf.data_len);
+ data = ab->GetBackingStore()->Data();
+ } else {
+ // Fast case. We reuse the global ArrayBuffer.
+ if (d->global_import_buf_.IsEmpty()) {
+ // Lazily initialize it.
+ DCHECK_NULL(d->global_import_buf_ptr_);
+ ab = v8::ArrayBuffer::New(d->isolate_, GLOBAL_IMPORT_BUF_SIZE);
+ d->global_import_buf_.Reset(d->isolate_, ab);
+ d->global_import_buf_ptr_ = ab->GetBackingStore()->Data();
+ } else {
+ DCHECK(d->global_import_buf_ptr_);
+ ab = d->global_import_buf_.Get(d->isolate_);
+ }
+ data = d->global_import_buf_ptr_;
+ }
+ memcpy(data, buf.data_ptr, buf.data_len);
+ auto view = v8::Uint8Array::New(ab, 0, buf.data_len);
+ return view;
+ */
+
+ // TODO(bartlomieju): for now skipping part with `global_import_buf_`
+ // and always creating new buffer
+ let ab = v8::ArrayBuffer::new(scope, buf.data_len);
+ let mut backing_store = ab.get_backing_store();
+ let data = backing_store.data();
+ let data: *mut u8 = data as *mut libc::c_void as *mut u8;
+ std::ptr::copy_nonoverlapping(buf.data_ptr, data, buf.data_len);
+ v8::Uint8Array::new(ab, 0, buf.data_len).expect("Failed to create UintArray8")
+}
+
pub extern "C" fn host_import_module_dynamically_callback(
context: v8::Local<v8::Context>,
referrer: v8::Local<v8::ScriptOrModule>,
@@ -52,10 +256,10 @@ pub extern "C" fn host_import_module_dynamically_callback(
let mut resolver_handle = v8::Global::new();
resolver_handle.set(scope, resolver);
- let import_id = deno_isolate.next_dyn_import_id_;
- deno_isolate.next_dyn_import_id_ += 1;
+ let import_id = deno_isolate.next_dyn_import_id;
+ deno_isolate.next_dyn_import_id += 1;
deno_isolate
- .dyn_import_map_
+ .dyn_import_map
.insert(import_id, resolver_handle);
deno_isolate.dyn_import_cb(&specifier_str, &referrer_name_str, import_id);
@@ -104,8 +308,8 @@ pub extern "C" fn message_callback(
let mut locker = v8::Locker::new(isolate);
let mut hs = v8::HandleScope::new(&mut locker);
let scope = hs.enter();
- assert!(!deno_isolate.context_.is_empty());
- let context = deno_isolate.context_.get(scope).unwrap();
+ assert!(!deno_isolate.global_context.is_empty());
+ let context = deno_isolate.global_context.get(scope).unwrap();
// TerminateExecution was called
if isolate.is_execution_terminating() {
@@ -115,7 +319,7 @@ pub extern "C" fn message_callback(
}
let json_str = deno_isolate.encode_message_as_json(scope, context, message);
- deno_isolate.last_exception_ = Some(json_str);
+ deno_isolate.last_exception = Some(json_str);
}
pub extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
@@ -125,10 +329,10 @@ pub extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
let deno_isolate: &mut Isolate =
unsafe { &mut *(isolate.get_data(0) as *mut Isolate) };
let mut locker = v8::Locker::new(isolate);
- assert!(!deno_isolate.context_.is_empty());
+ assert!(!deno_isolate.global_context.is_empty());
let mut hs = v8::HandleScope::new(&mut locker);
let scope = hs.enter();
- let mut context = deno_isolate.context_.get(scope).unwrap();
+ let mut context = deno_isolate.global_context.get(scope).unwrap();
context.enter();
let promise = msg.get_promise();
@@ -140,12 +344,12 @@ pub extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
let mut error_global = v8::Global::<v8::Value>::new();
error_global.set(scope, error);
deno_isolate
- .pending_promise_map_
+ .pending_promise_map
.insert(promise_id, error_global);
}
v8::PromiseRejectEvent::PromiseHandlerAddedAfterReject => {
if let Some(mut handle) =
- deno_isolate.pending_promise_map_.remove(&promise_id)
+ deno_isolate.pending_promise_map.remove(&promise_id)
{
handle.reset(scope);
}
@@ -160,6 +364,8 @@ pub extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
}
pub extern "C" fn print(info: &v8::FunctionCallbackInfo) {
+ #[allow(mutable_transmutes)]
+ #[allow(clippy::transmute_ptr_to_ptr)]
let info: &mut v8::FunctionCallbackInfo =
unsafe { std::mem::transmute(info) };
@@ -205,7 +411,7 @@ pub extern "C" fn recv(info: &v8::FunctionCallbackInfo) {
let mut hs = v8::HandleScope::new(&mut locker);
let scope = hs.enter();
- if !deno_isolate.recv_.is_empty() {
+ if !deno_isolate.js_recv_cb.is_empty() {
let msg = v8::String::new(scope, "Deno.core.recv already called.").unwrap();
isolate.throw_exception(msg.into());
return;
@@ -213,7 +419,7 @@ pub extern "C" fn recv(info: &v8::FunctionCallbackInfo) {
let recv_fn =
v8::Local::<v8::Function>::try_from(info.get_argument(0)).unwrap();
- deno_isolate.recv_.set(scope, recv_fn);
+ deno_isolate.js_recv_cb.set(scope, recv_fn);
}
pub extern "C" fn send(info: &v8::FunctionCallbackInfo) {
@@ -227,7 +433,7 @@ pub extern "C" fn send(info: &v8::FunctionCallbackInfo) {
let isolate = scope.isolate();
let deno_isolate: &mut Isolate =
unsafe { &mut *(isolate.get_data(0) as *mut Isolate) };
- assert!(!deno_isolate.context_.is_empty());
+ assert!(!deno_isolate.global_context.is_empty());
let op_id = v8::Local::<v8::Uint32>::try_from(info.get_argument(0))
.unwrap()
@@ -240,28 +446,25 @@ pub extern "C" fn send(info: &v8::FunctionCallbackInfo) {
let backing_store_ptr = backing_store.data() as *mut _ as *mut u8;
let view_ptr = unsafe { backing_store_ptr.add(view.byte_offset()) };
let view_len = view.byte_length();
- unsafe { deno_buf::from_raw_parts(view_ptr, view_len) }
+ unsafe { DenoBuf::from_raw_parts(view_ptr, view_len) }
})
- .unwrap_or_else(|_| deno_buf::empty());
+ .unwrap_or_else(|_| DenoBuf::empty());
let zero_copy: Option<PinnedBuf> =
v8::Local::<v8::ArrayBufferView>::try_from(info.get_argument(2))
.map(PinnedBuf::new)
.ok();
- // TODO: what's the point of this again?
- // DCHECK_NULL(d->current_args_);
- // d->current_args_ = &args;
- assert!(deno_isolate.current_args_.is_null());
- deno_isolate.current_args_ = info;
+ assert!(deno_isolate.current_send_cb_info.is_null());
+ deno_isolate.current_send_cb_info = info;
deno_isolate.pre_dispatch(op_id, control, zero_copy);
- if deno_isolate.current_args_.is_null() {
- // This indicates that deno_repond() was called already.
+ if deno_isolate.current_send_cb_info.is_null() {
+ // This indicates that respond() was called already.
} else {
// Asynchronous.
- deno_isolate.current_args_ = std::ptr::null();
+ deno_isolate.current_send_cb_info = std::ptr::null();
}
}
@@ -279,8 +482,8 @@ pub extern "C" fn eval_context(info: &v8::FunctionCallbackInfo) {
let isolate = scope.isolate();
let deno_isolate: &mut Isolate =
unsafe { &mut *(isolate.get_data(0) as *mut Isolate) };
- assert!(!deno_isolate.context_.is_empty());
- let context = deno_isolate.context_.get(scope).unwrap();
+ assert!(!deno_isolate.global_context.is_empty());
+ let context = deno_isolate.global_context.get(scope).unwrap();
let source = match v8::Local::<v8::String>::try_from(arg0) {
Ok(s) => s,
@@ -414,10 +617,10 @@ pub extern "C" fn error_to_json(info: &v8::FunctionCallbackInfo) {
let deno_isolate: &mut Isolate =
unsafe { &mut *(isolate.get_data(0) as *mut Isolate) };
let mut locker = v8::Locker::new(&isolate);
- assert!(!deno_isolate.context_.is_empty());
+ assert!(!deno_isolate.global_context.is_empty());
let mut hs = v8::HandleScope::new(&mut locker);
let scope = hs.enter();
- let context = deno_isolate.context_.get(scope).unwrap();
+ let context = deno_isolate.global_context.get(scope).unwrap();
// </Boilerplate>
let exception = info.get_argument(0);
let json_string =
@@ -465,27 +668,27 @@ pub extern "C" fn shared_getter(
let deno_isolate: &mut Isolate =
unsafe { &mut *(isolate.get_data(0) as *mut Isolate) };
- if deno_isolate.shared_.data_ptr.is_null() {
+ if deno_isolate.shared_buf.data_ptr.is_null() {
return;
}
// Lazily initialize the persistent external ArrayBuffer.
- if deno_isolate.shared_ab_.is_empty() {
+ if deno_isolate.shared_ab.is_empty() {
#[allow(mutable_transmutes)]
#[allow(clippy::transmute_ptr_to_ptr)]
let data_ptr: *mut u8 =
- unsafe { std::mem::transmute(deno_isolate.shared_.data_ptr) };
+ unsafe { std::mem::transmute(deno_isolate.shared_buf.data_ptr) };
let ab = unsafe {
v8::SharedArrayBuffer::new_DEPRECATED(
scope,
data_ptr as *mut c_void,
- deno_isolate.shared_.data_len,
+ deno_isolate.shared_buf.data_len,
)
};
- deno_isolate.shared_ab_.set(scope, ab);
+ deno_isolate.shared_ab.set(scope, ab);
}
- let shared_ab = deno_isolate.shared_ab_.get(scope).unwrap();
+ let shared_ab = deno_isolate.shared_ab.get(scope).unwrap();
scope.escape(shared_ab)
};
@@ -521,12 +724,9 @@ pub fn module_resolve_callback(
let req_str = req.to_rust_string_lossy(scope);
if req_str == specifier_str {
- let resolve_cb = deno_isolate.resolve_cb_.unwrap();
- let c_str = CString::new(req_str.to_string()).unwrap();
- let c_req_str: *const c_char = c_str.as_ptr() as *const c_char;
- let id = unsafe {
- resolve_cb(deno_isolate.resolve_context_, c_req_str, referrer_id)
- };
+ let ResolveContext { resolve_fn } =
+ unsafe { ResolveContext::from_raw_ptr(deno_isolate.resolve_context) };
+ let id = resolve_fn(&req_str, referrer_id);
let maybe_info = deno_isolate.get_module_info(id);
if maybe_info.is_none() {