diff --git a/Cargo.toml b/Cargo.toml index 2c46d0ea..c4ceb830 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,21 +3,30 @@ authors = ["David Flemström "] description = "High-level bindings to V8, the Javascript engine" documentation = "https://dflemstr.github.io/v8-rs/v8/index.html" homepage = "https://dflemstr.github.io/v8-rs" -keywords = ["v8", "javascript", "js", "ecmascript", "google"] +keywords = [ + "v8", + "javascript", + "js", + "ecmascript", + "google", +] license = "Apache-2.0" name = "v8" repository = "https://github.com/dflemstr/v8-rs" version = "0.9.6" [dependencies] -error-chain = "0.9.0" -lazy_static = "0.2.1" -num_cpus = "1.1.0" +error-chain = "0.11.0" +lazy_static = "1.0.0" +num_cpus = "1.8.0" +priority-queue = "0.4.5" [dependencies.v8-sys] path = "v8-sys" version = "0.14.0" [features] -shared = ["v8-sys/shared"] unstable = [] + +[workspace] +members = ["v8-sys"] diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 00000000..bf867e0a --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly diff --git a/src/allocator.rs b/src/allocator.rs index 9c2c0d18..243b09b5 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -1,46 +1,65 @@ //! Allocators for array buffers. -use v8_sys as v8; +use v8_sys; +use std::fmt; use std::os; use std::mem; +use std::ptr; /// A simple array buffer allocator that guarantees that all allocated -/// blocks are coercible to `Vec`s. -#[derive(Debug)] -pub struct Allocator(v8::ArrayBuffer_AllocatorPtr); +/// blocks are coercible to `Vec`s of `u8`. +pub struct Allocator(ptr::Shared); impl Allocator { /// Creates a new allocator. pub fn new() -> Allocator { - let raw = unsafe { v8::v8_ArrayBuffer_Allocator_Create(ALLOCATOR_FUNCTIONS) }; - if raw.is_null() { - panic!("Could not create ArrayBuffer::Allocator"); - } + let raw = unsafe { + ptr::Shared::new(v8_sys::impls::CreateArrayBufferAllocator( + ALLOCATOR_FUNCTIONS, + ptr::null_mut(), + )) + }.expect("could not create ArrayBuffer::Allocator"); Allocator(raw) } /// Returns the underlying raw pointer behind this allocator. - pub fn as_raw(&self) -> v8::ArrayBuffer_AllocatorPtr { - self.0 + pub fn as_ptr(&self) -> *mut v8_sys::ArrayBuffer_Allocator { + self.0.as_ptr() + } +} + +impl fmt::Debug for Allocator { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Allocator({:?})", unsafe { self.0.as_ref() }) } } impl Drop for Allocator { fn drop(&mut self) { unsafe { - v8::v8_ArrayBuffer_Allocator_Destroy(self.0); + v8_sys::ArrayBuffer_Allocator_Allocator_destructor(self.0.as_ptr()); } } } -const ALLOCATOR_FUNCTIONS: v8::v8_AllocatorFunctions = v8::v8_AllocatorFunctions { - Allocate: Some(allocate), - AllocateUninitialized: Some(allocate_uninitialized), - Free: Some(free), -}; +const ALLOCATOR_FUNCTIONS: v8_sys::impls::ArrayBufferAllocatorFunctions = + v8_sys::impls::ArrayBufferAllocatorFunctions { + Destroy: None, + Allocate: Some(allocate), + AllocateUninitialized: Some(allocate_uninitialized), + Reserve: None, + Free: Some(free), + FreeMode: Some(free_mode), + SetProtection: None, + }; -extern "C" fn allocate(length: usize) -> *mut os::raw::c_void { +unsafe extern "C" fn allocate( + _this: *mut os::raw::c_void, + _fallback_fn: Option *mut os::raw::c_void>, + _fallback_arg: *mut os::raw::c_void, + length: usize, +) -> *mut os::raw::c_void { let mut data = Vec::with_capacity(length); data.resize(length, 0u8); let ptr = data.as_mut_ptr(); @@ -49,12 +68,14 @@ extern "C" fn allocate(length: usize) -> *mut os::raw::c_void { ptr as *mut os::raw::c_void } -extern "C" fn allocate_uninitialized(length: usize) -> *mut os::raw::c_void { +unsafe extern "C" fn allocate_uninitialized( + _this: *mut os::raw::c_void, + _fallback_fn: Option *mut os::raw::c_void>, + _fallback_arg: *mut os::raw::c_void, + length: usize, +) -> *mut os::raw::c_void { let mut data = Vec::with_capacity(length); - - unsafe { - data.set_len(length); - } + data.set_len(length); let ptr = data.as_mut_ptr(); mem::forget(data); @@ -62,7 +83,34 @@ extern "C" fn allocate_uninitialized(length: usize) -> *mut os::raw::c_void { ptr as *mut os::raw::c_void } -unsafe extern "C" fn free(data: *mut os::raw::c_void, length: usize) { +unsafe extern "C" fn free( + _this: *mut os::raw::c_void, + _fallback_fn: Option, + _fallback_arg: *mut os::raw::c_void, + data: *mut os::raw::c_void, + length: usize, +) { // TODO: restore `cap` here? Can this possibly leak memory? drop(Vec::from_raw_parts(data, length, length)); } + +unsafe extern "C" fn free_mode( + _this: *mut os::raw::c_void, + fallback_fn: Option< + unsafe extern "C" fn(*mut os::raw::c_void, + *mut os::raw::c_void, + usize, + v8_sys::ArrayBuffer_Allocator_AllocationMode), + >, + fallback_arg: *mut os::raw::c_void, + data: *mut os::raw::c_void, + length: usize, + mode: v8_sys::ArrayBuffer_Allocator_AllocationMode, +) { + if mode == v8_sys::ArrayBuffer_Allocator_AllocationMode_kNormal { + // TODO: restore `cap` here? Can this possibly leak memory? + drop(Vec::from_raw_parts(data, length, length)); + } else { + fallback_fn.unwrap()(fallback_arg, data, length, mode); + } +} diff --git a/src/context.rs b/src/context.rs index 50274d91..c23fcc6e 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,40 +1,46 @@ //! Execution contexts and sandboxing. -use v8_sys as v8; +use v8_sys; +use std::ptr; use isolate; -use util; +use handle; use value; /// A sandboxed execution context with its own set of built-in objects and functions. #[derive(Debug)] -pub struct Context(isolate::Isolate, v8::ContextRef); +pub struct Context(v8_sys::Context); /// A guard that keeps a context bound while it is in scope. #[must_use] -pub struct ContextGuard<'a>(&'a Context); +pub struct Scope<'c>(&'c mut Context); impl Context { /// Creates a new context and returns a handle to the newly allocated context. - pub fn new(isolate: &isolate::Isolate) -> Context { + pub fn new<'i, 's>( + scope: &'s handle::Scope, + isolate: &'i isolate::Isolate, + ) -> handle::Local<'i, 's, Context> { unsafe { - Context(isolate.clone(), - util::invoke(isolate, |c| v8::v8_Context_New(c)).unwrap()) + handle::Local::new(v8_sys::Context::New( + isolate.as_ptr(), + ptr::null_mut(), + handle::MaybeLocal::empty().into_raw(), + handle::MaybeLocal::empty().into_raw(), + v8_sys::DeserializeInternalFieldsCallback { + callback: None, + data: ptr::null_mut(), + }, + )) } } /// Binds the context to the current scope. /// /// Within this scope, functionality that relies on implicit contexts will work. - pub fn make_current(&self) -> ContextGuard { - self.enter(); - ContextGuard(self) - } - - fn enter(&self) { - unsafe { util::invoke(&self.0, |c| v8::v8_Context_Enter(c, self.1)).unwrap() } - } - - fn exit(&self) { - unsafe { util::invoke(&self.0, |c| v8::v8_Context_Exit(c, self.1)).unwrap() } + pub fn scope(&mut self) -> Scope { + unsafe { + self.0.Enter(); + } + Scope(self) } /// Returns the global proxy object. @@ -46,29 +52,25 @@ impl Context { /// Please note that changes to global proxy object prototype most probably would break VM---v8 /// expects only global object as a prototype of global proxy object. /// - pub fn global(&self) -> value::Object { + pub fn global(&self) -> handle::Local { unsafe { - value::Object::from_raw(&self.0, - util::invoke(&self.0, |c| v8::v8_Context_Global(c, self.1)) - .unwrap()) + handle::Local::new(self.0.Global()) } } +} - /// Creates a context from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::ContextRef) -> Context { - Context(isolate.clone(), raw) +impl<'c> Scope<'c> { + pub fn context(&self) -> &Context { + &self.0 } - /// Returns the underlying raw pointer behind this context. - pub fn as_raw(&self) -> v8::ContextRef { - self.1 + pub fn context_mut(&mut self) -> &mut Context { + &mut self.0 } } -reference!(Context, v8::v8_Context_CloneRef, v8::v8_Context_DestroyRef); - -impl<'a> Drop for ContextGuard<'a> { +impl<'c> Drop for Scope<'c> { fn drop(&mut self) { - self.0.exit() + unsafe { (self.0).0.Exit() } } } diff --git a/src/error.rs b/src/error.rs index 1345539a..b258e5c8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,8 +1,10 @@ //! Error types and utilities. use std::fmt; -use v8_sys as v8; +use std::ptr; +use v8_sys; use context; +use handle; use isolate; use util; use value; @@ -35,60 +37,45 @@ pub struct CapturedStackFrame { /// An error message. #[derive(Debug)] -pub struct Message(isolate::Isolate, v8::MessageRef); +pub struct Message(v8_sys::Message); /// A stack trace, that is bound to an isolate. #[derive(Debug)] -pub struct StackTrace(isolate::Isolate, v8::StackTraceRef); +pub struct StackTrace(v8_sys::StackTrace); /// A stack frame, that is bound to an isolate. #[derive(Debug)] -pub struct StackFrame(isolate::Isolate, v8::StackFrameRef); +pub struct StackFrame(v8_sys::StackFrame); impl Message { // TODO: pub fn get_script_origin(&self) /// The error message string. - pub fn get(&self, context: &context::Context) -> value::String { - let _g = context.make_current(); - unsafe { - value::String::from_raw(&self.0, - util::invoke_ctx(&self.0, - context, - |c| v8::v8_Message_Get(c, self.1)) - .unwrap()) - } + pub fn get(&self) -> handle::Local { + unsafe { handle::Local::new(self.0.Get()) } } /// The stack trace to the point where the error was generated. - pub fn get_stack_trace(&self) -> StackTrace { - let raw = - unsafe { util::invoke(&self.0, |c| v8::v8_Message_GetStackTrace(c, self.1)).unwrap() }; - - StackTrace(self.0.clone(), raw) + pub fn get_stack_trace(&self) -> handle::Local { + unsafe { handle::Local::new(self.0.GetStackTrace()) } } - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::MessageRef) -> Message { - Message(isolate.clone(), raw) + pub unsafe fn from_raw(raw: v8_sys::Message) -> Message { + Message(raw) } } impl StackTrace { /// The stack frames that this stack trace consists of. - pub fn get_frames(&self) -> Vec { - let count = - unsafe { util::invoke(&self.0, |c| v8::v8_StackTrace_GetFrameCount(c, self.1)).unwrap() }; + pub fn get_frames(&self) -> Vec> { + let count = unsafe { self.0.GetFrameCount() }; let mut result = Vec::with_capacity(count as usize); for i in 0..count { - let raw_frame = unsafe { - util::invoke(&self.0, |c| v8::v8_StackTrace_GetFrame(c, self.1, i as u32)).unwrap() - }; - let frame = StackFrame(self.0.clone(), raw_frame); - result.push(frame); + result.push(unsafe { self.0.GetFrame(i) }); } - result + unsafe { result } } /// Creates a captured version of this stack trace, that doesn't retain a reference to its @@ -107,43 +94,42 @@ impl StackFrame { /// The line number at which this stack frame was pushed. pub fn get_line_number(&self) -> u32 { unsafe { - util::invoke(&self.0, |c| v8::v8_StackFrame_GetLineNumber(c, self.1)).unwrap() as u32 + self.0.GetLineNumber() as u32 } } /// The column number at which this stack frame was pushed. pub fn get_column(&self) -> u32 { - unsafe { util::invoke(&self.0, |c| v8::v8_StackFrame_GetColumn(c, self.1)).unwrap() as u32 } + unsafe { self.0.GetColumn() as u32 } } /// The script file name in which this stack frame was pushed. - pub fn get_script_name(&self) -> Option { + pub fn get_script_name(&self) -> Option> { unsafe { - let raw = util::invoke(&self.0, |c| v8::v8_StackFrame_GetScriptName(c, self.1)).unwrap(); + let raw = self.0.GetScriptName(); if raw.is_null() { None } else { - Some(value::String::from_raw(&self.0, raw)) + Some(handle::Local::new(raw)) } } } /// The function name in which this stack frame was pushed. - pub fn get_function_name(&self) -> value::String { + pub fn get_function_name(&self) -> handle::Local { unsafe { - let raw = util::invoke(&self.0, |c| v8::v8_StackFrame_GetFunctionName(c, self.1)).unwrap(); - value::String::from_raw(&self.0, raw) + handle::Local::new(self.0.GetFunctionName()) } } /// Whether this stack frame is part of an eval call. pub fn is_eval(&self) -> bool { - unsafe { util::invoke(&self.0, |c| v8::v8_StackFrame_IsEval(c, self.1)).unwrap() } + unsafe { self.0.IsEval() } } /// Whether this stack frame is part of a constructor call. pub fn is_constructor(&self) -> bool { - unsafe { util::invoke(&self.0, |c| v8::v8_StackFrame_IsConstructor(c, self.1)).unwrap() } + unsafe { self.0.IsConstructor() } } /// Creates a captured version of this stack frame, that doesn't retain a reference to its @@ -168,7 +154,7 @@ impl StackFrame { impl fmt::Display for CapturedStackTrace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for frame in self.frames.iter() { - try!(writeln!(f, "{}", frame)); + writeln!(f, "{}", frame)?; } Ok(()) } @@ -176,43 +162,35 @@ impl fmt::Display for CapturedStackTrace { impl fmt::Display for CapturedStackFrame { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(write!(f, " at ")); + write!(f, " at ")?; if self.is_constructor { - try!(write!(f, "new ")); + write!(f, "new ")?; } if let Some(ref function_name) = self.function_name { - try!(write!(f, "{} (", function_name)); + write!(f, "{} (", function_name)?; if self.is_eval { - try!(write!(f, "eval ")); + write!(f, "eval ")?; } - try!(write!(f, - "{}:{}:{})", - self.script_name.as_ref().map(|n| n.as_str()).unwrap_or(""), - self.line, - self.column)); + write!(f, + "{}:{}:{})", + self.script_name.as_ref().map(|n| n.as_str()).unwrap_or(""), + self.line, + self.column)?; } else { if self.is_eval { - try!(write!(f, "eval ")); + write!(f, "eval ")?; } - try!(write!(f, - "{}:{}:{}", - self.script_name.as_ref().map(|n| n.as_str()).unwrap_or(""), - self.line, - self.column)); + write!(f, + "{}:{}:{}", + self.script_name.as_ref().map(|n| n.as_str()).unwrap_or(""), + self.line, + self.column)?; } Ok(()) } } - -reference!(Message, v8::v8_Message_CloneRef, v8::v8_Message_DestroyRef); -reference!(StackTrace, - v8::v8_StackTrace_CloneRef, - v8::v8_StackTrace_DestroyRef); -reference!(StackFrame, - v8::v8_StackFrame_CloneRef, - v8::v8_StackFrame_DestroyRef); diff --git a/src/handle.rs b/src/handle.rs new file mode 100644 index 00000000..67a1ab6c --- /dev/null +++ b/src/handle.rs @@ -0,0 +1,73 @@ +use v8_sys; +use std::convert; +use std::marker; +use std::mem; +use std::ops; +use std::ptr; +use isolate; + +#[derive(Debug)] +pub struct Scope<'i>(v8_sys::HandleScope, marker::PhantomData<&'i isolate::Isolate>); + +#[derive(Debug, Copy, Clone)] +pub struct Local<'i, 's, A>(v8_sys::Local, marker::PhantomData<&'s Scope<'i>>) + where + 'i: 's; + +#[derive(Debug, Copy, Clone)] +pub struct MaybeLocal<'i, 's, A>(v8_sys::MaybeLocal, marker::PhantomData<&'s Scope<'i>>) + where + 'i: 's; + +#[derive(Debug, Copy, Clone)] +pub struct Eternal<'i, A>(v8_sys::Eternal, marker::PhantomData<&'i isolate::Isolate>); + +#[derive(Debug, Copy, Clone)] +pub struct Persistent<'i, A>(v8_sys::Persistent, marker::PhantomData<&'i isolate::Isolate>); + +impl<'i, 's, A> Local<'i, 's, A> { + pub unsafe fn new(value: v8_sys::Local) -> Local<'i, 's, A> { + assert_eq!(mem::size_of::(), mem::size_of::()); + Local(mem::transmute(value), marker::PhantomData) + } + + pub fn into_raw(self) -> v8_sys::Local { + self.0 + } +} + +impl<'i, 's, A> convert::From> for Local<'i, 's, A> { + fn from(other: v8_sys::Local) -> Self { + Local(other, marker::PhantomData) + } +} + +impl<'i, 's, A> ops::Deref for Local<'i, 's, A> { + type Target = A; + + fn deref(&self) -> &Self::Target { + unsafe { self.0.val_.as_ref() }.unwrap() + } +} + +impl<'i, 's, A> ops::DerefMut for Local<'i, 's, A> { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { self.0.val_.as_mut() }.unwrap() + } +} + +impl<'i, 's, A> MaybeLocal<'i, 's, A> { + pub fn empty() -> MaybeLocal<'i, 's, A> { + MaybeLocal( + v8_sys::MaybeLocal { + val_: ptr::null_mut(), + _phantom_0: marker::PhantomData, + }, + marker::PhantomData, + ) + } + + pub fn into_raw(self) -> v8_sys::MaybeLocal { + self.0 + } +} diff --git a/src/isolate.rs b/src/isolate.rs index d86cf2bd..a1a29564 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -25,16 +25,19 @@ //! `Isolate::builder().supports_idle_tasks(true).build()`. The user should then regularly call //! `isolate.run_idle_tasks(deadline)` to run any pending idle tasks. -use std::cmp; +use std::cell; use std::collections; +use std::fmt; use std::mem; use std::os; +use std::ptr; +use std::rc; use std::sync; use std::time; -use v8_sys as v8; +use v8_sys; use allocator; -use context; use platform; +use priority_queue; static INITIALIZE: sync::Once = sync::ONCE_INIT; @@ -44,25 +47,24 @@ static INITIALIZE: sync::Once = sync::ONCE_INIT; /// isolates. The embedder can create multiple isolates and use them in parallel in multiple /// threads. An isolate can be entered by at most one thread at any given time. The /// Locker/Unlocker API must be used to synchronize. -#[derive(Debug)] -pub struct Isolate(v8::IsolatePtr); +pub struct Isolate(ptr::Shared); /// A builder for isolates. Can be converted into an isolate with the `build` method. pub struct Builder { supports_idle_tasks: bool, } +#[must_use] +pub struct Scope<'i>(&'i mut Isolate); + #[derive(Debug)] struct Data { - count: usize, + count: cell::Cell, _allocator: allocator::Allocator, - task_queue: collections::BinaryHeap, - idle_task_queue: Option>, + task_queue: rc::Rc>>, + idle_task_queue: Option>>>, } -#[derive(Debug, Eq, PartialEq)] -struct ScheduledTask(time::Instant, platform::Task); - const DATA_PTR_SLOT: u32 = 0; impl Isolate { @@ -76,31 +78,38 @@ impl Isolate { Builder { supports_idle_tasks: false } } - /// Creates a data from a set of raw pointers. + /// Creates a data from a raw pointer. /// /// This isolate must at some point have been created by `Isolate::new`, since this library /// expects isolates to be configured a certain way and contain embedder information. - pub unsafe fn from_raw(raw: v8::IsolatePtr) -> Isolate { - let result = Isolate(raw); - result.get_data().count += 1; + pub unsafe fn from_ptr(raw: *mut v8_sys::Isolate) -> Isolate { + let mut result = Isolate(ptr::Shared::new(raw).unwrap()); + *result.data_mut().count.get_mut() += 1; result } /// Returns the underlying raw pointer behind this isolate. - pub fn as_raw(&self) -> v8::IsolatePtr { - self.0 + pub fn as_ptr(&self) -> *mut v8_sys::Isolate { + self.0.as_ptr() + } + + pub fn scope(&mut self) -> Scope { + unsafe { self.0.as_mut().Enter() }; + Scope(self) } + /* /// Returns the context bound to the current thread for this isolate. /// /// A context will be bound by for example `Context::make_current`, or while inside of a /// function callback. pub fn current_context(&self) -> Option { unsafe { - let raw = v8::v8_Isolate_GetCurrentContext(self.as_raw()).as_mut(); + let raw = self.isolate(self.as_raw()).as_mut(); raw.map(|r| context::Context::from_raw(self, r)) } } + */ /// Runs all enqueued tasks until there are no more tasks available. pub fn run_enqueued_tasks(&self) { @@ -110,11 +119,16 @@ impl Isolate { /// Runs a single enqueued task, if there is one. Returns `true` if a task was executed, and /// `false` if there are no pending tasks to run. pub fn run_enqueued_task(&self) -> bool { - let data = unsafe { self.get_data() }; + let data = self.data(); let now = time::Instant::now(); - if data.task_queue.peek().map(|t| t.0 > now).unwrap_or(false) { - let task = data.task_queue.pop().unwrap().1; + if data.task_queue + .borrow() + .peek() + .map(|(_, p)| *p > now) + .unwrap_or(false) + { + let task = data.task_queue.borrow_mut().pop().unwrap().0; task.run(); true } else { @@ -142,12 +156,13 @@ impl Isolate { /// execution of the task will take less time than the specified deadline. Returns `true` if a /// task was executed, and `false` if there are no pending tasks to run. pub fn run_idle_task(&self, deadline: time::Duration) -> bool { - let data = unsafe { self.get_data() }; + let data = self.data(); if let Some(idle_task) = data.idle_task_queue - .as_mut() - .map(|q| q.pop_front()) - .unwrap_or(None) { + .as_ref() + .map(|q| q.borrow_mut().pop_front()) + .unwrap_or(None) + { idle_task.run(deadline); true } else { @@ -157,53 +172,81 @@ impl Isolate { /// Enqueues the specified task to run as soon as possible. pub fn enqueue_task(&self, task: platform::Task) { - let scheduled_task = ScheduledTask(time::Instant::now(), task); - unsafe { self.get_data() }.task_queue.push(scheduled_task); + self.data().task_queue.borrow_mut().push( + task, + time::Instant::now(), + ); } /// Enqueues the specified task to run after the specified delay has passed. pub fn enqueue_delayed_task(&self, delay: time::Duration, task: platform::Task) { - let scheduled_task = ScheduledTask(time::Instant::now() + delay, task); - unsafe { self.get_data() }.task_queue.push(scheduled_task); + self.data().task_queue.borrow_mut().push( + task, + time::Instant::now() + delay, + ); } /// Enqueues a task to be run when the isolate is considered to be "idle." pub fn enqueue_idle_task(&self, idle_task: platform::IdleTask) { - unsafe { self.get_data() }.idle_task_queue.as_mut().unwrap().push_back(idle_task); + self.data() + .idle_task_queue + .as_ref() + .unwrap() + .borrow_mut() + .push_back(idle_task); } /// Whether this isolate was configured to support idle tasks. pub fn supports_idle_tasks(&self) -> bool { - unsafe { self.get_data() }.idle_task_queue.is_some() + self.data().idle_task_queue.is_some() } - unsafe fn get_data_ptr(&self) -> *mut Data { - v8::v8_Isolate_GetData(self.0, DATA_PTR_SLOT) as *mut Data + fn data_ptr(&self) -> *mut Data { + unsafe { (*self.0.as_ptr()).GetData(DATA_PTR_SLOT) as *mut Data } } - unsafe fn get_data(&self) -> &mut Data { - self.get_data_ptr().as_mut().unwrap() + fn data(&self) -> &Data { + unsafe { self.data_ptr().as_ref().unwrap() } + } + + fn data_mut(&mut self) -> &mut Data { + unsafe { self.data_ptr().as_mut().unwrap() } } } impl Clone for Isolate { fn clone(&self) -> Isolate { - unsafe { - self.get_data().count += 1; - } + let data = self.data(); + let new_count = data.count.get() + 1; + data.count.set(new_count); Isolate(self.0) } } +impl fmt::Debug for Isolate { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Isolate({:?}, {:?})", + unsafe { self.0.as_ref() }, + self.data() + ) + } +} + impl Drop for Isolate { fn drop(&mut self) { - unsafe { - let ref mut count = self.get_data().count; - *count -= 1; + let new_count = { + let data = self.data(); + let new_count = data.count.get() - 1; + data.count.set(new_count); + new_count + }; - if *count == 0 { - drop(Box::from_raw(self.get_data_ptr())); - v8::v8_Isolate_Dispose(self.0); + unsafe { + if new_count == 0 { + drop(Box::from_raw(self.data_ptr())); + self.0.as_mut().Dispose(); } } } @@ -223,61 +266,76 @@ impl Builder { let allocator = allocator::Allocator::new(); - let raw = unsafe { v8::v8_Isolate_New(allocator.as_raw()) }; - if raw.is_null() { - panic!("Could not create Isolate"); - } + let mut raw = unsafe { + let mut params: v8_sys::Isolate_CreateParams = mem::zeroed(); + params.allow_atomics_wait = true; + params.array_buffer_allocator = allocator.as_ptr(); + ptr::Shared::new(v8_sys::Isolate::New(¶ms)).expect("Could not create Isolate") + }; unsafe { - assert!(v8::v8_Isolate_GetNumberOfDataSlots(raw) > 0); + assert!(v8_sys::Isolate::GetNumberOfDataSlots() > 0); } let idle_task_queue = if self.supports_idle_tasks { - Some(collections::VecDeque::new()) + Some(rc::Rc::new( + cell::RefCell::new(collections::VecDeque::new()), + )) } else { None }; let data = Data { - count: 1, + count: cell::Cell::new(1), _allocator: allocator, - task_queue: collections::BinaryHeap::new(), + task_queue: rc::Rc::new(cell::RefCell::new(priority_queue::PriorityQueue::new())), idle_task_queue: idle_task_queue, }; let data_ptr: *mut Data = Box::into_raw(Box::new(data)); unsafe { - v8::v8_Isolate_SetData(raw, DATA_PTR_SLOT, data_ptr as *mut os::raw::c_void); - v8::v8_Isolate_SetCaptureStackTraceForUncaughtExceptions_Detailed(raw, true, 1024); + raw.as_mut().SetData( + DATA_PTR_SLOT, + data_ptr as *mut os::raw::c_void, + ); + raw.as_mut().SetCaptureStackTraceForUncaughtExceptions( + true, + 1024, + v8_sys::StackTrace_StackTraceOptions_kDetailed, + ); } Isolate(raw) } } -impl PartialOrd for ScheduledTask { - fn partial_cmp(&self, other: &ScheduledTask) -> Option { - Some(self.cmp(other)) +impl<'i> Scope<'i> { + pub fn isolate(&self) -> &Isolate { + &self.0 + } + + pub fn isolate_mut(&mut self) -> &mut Isolate { + &mut self.0 } } -impl Ord for ScheduledTask { - fn cmp(&self, other: &ScheduledTask) -> cmp::Ordering { - self.0.cmp(&other.0).reverse() +impl<'i> Drop for Scope<'i> { + fn drop(&mut self) { + unsafe { (self.0).0.as_mut().Exit() } } } fn ensure_initialized() { INITIALIZE.call_once(|| { unsafe { - v8::v8_V8_InitializeICU(); + v8_sys::V8_InitializeICU(ptr::null()); let platform = platform::Platform::new(); - v8::v8_V8_InitializePlatform(platform.as_raw()); + v8_sys::V8_InitializePlatform(platform.as_ptr()); // TODO: implement some form of cleanup mem::forget(platform); - v8::v8_V8_Initialize(); + v8_sys::V8_Initialize(); } }); } diff --git a/src/lib.rs b/src/lib.rs index 7e296c3e..3ed17e23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,13 +48,14 @@ //! //! [1]: https://developers.google.com/v8/ -#![cfg_attr(all(feature="unstable", test), feature(test))] +#![feature(shared, unique)] #[macro_use] extern crate error_chain; #[macro_use] extern crate lazy_static; extern crate num_cpus; +extern crate priority_queue; extern crate v8_sys; mod allocator; @@ -64,15 +65,16 @@ mod util; pub mod context; pub mod error; +pub mod handle; pub mod isolate; -pub mod script; +//pub mod script; pub mod template; pub mod value; -pub use context::Context; -pub use isolate::Isolate; -pub use script::Script; -pub use value::Value; +//pub use context::Context; +//pub use isolate::Isolate; +//pub use script::Script; +//pub use value::Value; #[cfg(test)] mod tests { @@ -83,8 +85,13 @@ mod tests { let context = Context::new(&isolate); let name = value::String::from_str(&isolate, "test.js"); let source = value::String::from_str(&isolate, source); - let script = try!(Script::compile_with_name(&isolate, &context, &name, &source)); - let result = try!(script.run(&context)); + let script = Script::compile_with_name( + &isolate, + &context, + &name, + &source, + )?; + let result = script.run(&context)?; Ok((isolate, context, result)) } @@ -460,7 +467,8 @@ mod tests { #[test] fn eval_exception_stack() { - let result = eval(r#" + let result = eval( + r#" (function() { function x() { y(); @@ -476,16 +484,19 @@ mod tests { } x(); })(); -"#); +"#, + ); let error = result.unwrap_err(); match error.kind() { &error::ErrorKind::Javascript(ref msg, ref stack_trace) => { assert_eq!("Uncaught Error: x", msg); - assert_eq!(" at new w (test.js:13:11)\n at z (test.js:10:5)\n at eval \ + assert_eq!( + " at new w (test.js:13:11)\n at z (test.js:10:5)\n at eval \ :1:1\n at y (test.js:7:5)\n at x (test.js:4:5)\n at \ test.js:15:3\n at test.js:16:3\n", - format!("{}", stack_trace)); + format!("{}", stack_trace) + ); } x => panic!("Unexpected error kind: {:?}", x), } @@ -496,10 +507,12 @@ mod tests { let isolate = Isolate::new(); let context = Context::new(&isolate); - let function = value::Function::new(&isolate, - &context, - 1, - Box::new(|mut info| Ok(info.args.remove(0)))); + let function = value::Function::new( + &isolate, + &context, + 1, + Box::new(|mut info| Ok(info.args.remove(0))), + ); let param = value::Integer::new(&isolate, 42); let result = function.call(&context, &[¶m]).unwrap(); @@ -513,20 +526,22 @@ mod tests { let fi = i.clone(); let fc = c.clone(); - let f = value::Function::new(&i, - &c, - 2, - Box::new(move |info| { - assert_eq!(2, info.length); - let ref a = info.args[0]; - assert!(a.is_int32()); - let a = a.int32_value(&fc); - let ref b = info.args[1]; - assert!(b.is_int32()); - let b = b.int32_value(&fc); - - Ok(value::Integer::new(&fi, a + b).into()) - })); + let f = value::Function::new( + &i, + &c, + 2, + Box::new(move |info| { + assert_eq!(2, info.length); + let ref a = info.args[0]; + assert!(a.is_int32()); + let a = a.int32_value(&fc); + let ref b = info.args[1]; + assert!(b.is_int32()); + let b = b.int32_value(&fc); + + Ok(value::Integer::new(&fi, a + b).into()) + }), + ); let k = value::String::from_str(&i, "f"); c.global().set(&c, &k, &f); @@ -654,10 +669,12 @@ mod tests { let context = Context::new(&isolate); let param = value::Integer::new(&isolate, 42); - let function = value::Function::new(&isolate, - &context, - 1, - Box::new(|mut info| Ok(info.args.remove(0)))); + let function = value::Function::new( + &isolate, + &context, + 1, + Box::new(|mut info| Ok(info.args.remove(0))), + ); (function, context, param) }; @@ -672,14 +689,16 @@ mod tests { let context = Context::new(&isolate); let closure_isolate = isolate.clone(); - let f = value::Function::new(&isolate, - &context, - 0, - Box::new(move |_| { - let msg = value::String::from_str(&closure_isolate, "FooBar"); - let ex = value::Exception::error(&closure_isolate, &msg); - Err(ex) - })); + let f = value::Function::new( + &isolate, + &context, + 0, + Box::new(move |_| { + let msg = value::String::from_str(&closure_isolate, "FooBar"); + let ex = value::Exception::error(&closure_isolate, &msg); + Err(ex) + }), + ); let name = value::String::from_str(&isolate, "f"); context.global().set(&context, &name, &f); @@ -702,13 +721,15 @@ mod tests { let foo = Foo { msg: "Hello, World!".into() }; let closure_isolate = isolate.clone(); - value::Function::new(&isolate, - &context, - 0, - Box::new(move |_| { - assert_eq!("Hello, World!", &foo.msg); - Ok(value::undefined(&closure_isolate).into()) - })) + value::Function::new( + &isolate, + &context, + 0, + Box::new(move |_| { + assert_eq!("Hello, World!", &foo.msg); + Ok(value::undefined(&closure_isolate).into()) + }), + ) }; let bar = Foo { msg: "Goodbye, World!".into() }; @@ -724,15 +745,17 @@ mod tests { } #[test] - #[should_panic="You dun goofed"] + #[should_panic = "You dun goofed"] fn propagate_panic() { let isolate = Isolate::new(); let context = Context::new(&isolate); - let f = value::Function::new(&isolate, - &context, - 0, - Box::new(|_| panic!("You dun goofed"))); + let f = value::Function::new( + &isolate, + &context, + 0, + Box::new(|_| panic!("You dun goofed")), + ); f.call(&context, &[]).unwrap(); } @@ -742,17 +765,21 @@ mod tests { let isolate = Isolate::new(); let context = Context::new(&isolate); - let f = value::Function::new(&isolate, - &context, - 0, - Box::new(|_| panic!("Something: {}", 42))); + let f = value::Function::new( + &isolate, + &context, + 0, + Box::new(|_| panic!("Something: {}", 42)), + ); let f_key = value::String::from_str(&isolate, "f"); context.global().set(&context, &f_key, &f); - let source = value::String::from_str(&isolate, - "(function() { try { f(); } catch (e) { return \ - e.message; } })()"); + let source = value::String::from_str( + &isolate, + "(function() { try { f(); } catch (e) { return \ + e.message; } })()", + ); let script = Script::compile(&isolate, &context, &source).unwrap(); let result = script.run(&context).unwrap(); @@ -762,7 +789,7 @@ mod tests { } } -#[cfg(all(feature="unstable", test))] +#[cfg(all(feature = "unstable", test))] mod benches { extern crate test; @@ -788,10 +815,12 @@ mod benches { let isolate = Isolate::new(); let context = Context::new(&isolate); - let function = value::Function::new(&isolate, - &context, - 1, - Box::new(|mut info| Ok(info.args.remove(0)))); + let function = value::Function::new( + &isolate, + &context, + 1, + Box::new(|mut info| Ok(info.args.remove(0))), + ); let param = value::Integer::new(&isolate, 42); bencher.iter(|| function.call(&context, &[¶m]).unwrap()); diff --git a/src/platform.rs b/src/platform.rs index ee970698..c01cc940 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -1,4 +1,8 @@ -use v8_sys as v8; +use v8_sys; +use std::fmt; +use std::hash; +use std::os; +use std::ptr; use std::thread; use std::time; use num_cpus; @@ -14,37 +18,41 @@ lazy_static! { /// scheduling. // TODO: make this use some kind of main loop/work stealing queue // instead. -#[derive(Debug)] -pub struct Platform(v8::PlatformPtr); +pub struct Platform(ptr::Unique); -#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct Task(v8::TaskPtr); +pub struct Task(ptr::Unique); unsafe impl Send for Task {} -#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] -pub struct IdleTask(v8::IdleTaskPtr); +pub struct IdleTask(ptr::Unique); impl Platform { pub fn new() -> Platform { - let raw = unsafe { v8::v8_Platform_Create(PLATFORM_FUNCTIONS) }; - - if raw.is_null() { - panic!("Could not create Platform") - } + let raw = unsafe { + ptr::Unique::new(v8_sys::impls::CreatePlatform( + PLATFORM_FUNCTIONS, + ptr::null_mut(), + )) + }.expect("could not create Platform"); Platform(raw) } - pub fn as_raw(&self) -> v8::PlatformPtr { - self.0 + pub fn as_ptr(&self) -> *mut v8_sys::Platform { + self.0.as_ptr() + } +} + +impl fmt::Debug for Platform { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Platform({:?})", unsafe { self.0.as_ref() }) } } impl Drop for Platform { fn drop(&mut self) { unsafe { - v8::v8_Platform_Destroy(self.0); + v8_sys::Platform_Platform_destructor(self.0.as_ptr()); } } } @@ -52,15 +60,43 @@ impl Drop for Platform { impl Task { pub fn run(&self) { unsafe { - v8::v8_Task_Run(self.0); + v8_sys::Task_Run(self.0.as_ptr() as *mut os::raw::c_void); } } + + pub fn as_ptr(&self) -> *mut v8_sys::Task { + self.0.as_ptr() + } + + pub unsafe fn from_ptr(ptr: *mut v8_sys::Task) -> Task { + Task(ptr::Unique::new(ptr).unwrap()) + } +} + +impl fmt::Debug for Task { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Task({:?})", unsafe { self.0.as_ref() }) + } +} + +impl PartialEq for Task { + fn eq(&self, other: &Task) -> bool { + self.as_ptr() == other.as_ptr() + } +} + +impl Eq for Task {} + +impl hash::Hash for Task { + fn hash(&self, state: &mut H) { + self.as_ptr().hash(state) + } } impl Drop for Task { fn drop(&mut self) { unsafe { - v8::v8_Task_Destroy(self.0); + v8_sys::Task_Task_destructor(self.0.as_ptr()); } } } @@ -68,20 +104,37 @@ impl Drop for Task { impl IdleTask { pub fn run(&self, deadline: time::Duration) { unsafe { - v8::v8_IdleTask_Run(self.0, duration_to_seconds(deadline)); + v8_sys::IdleTask_Run( + self.0.as_ptr() as *mut os::raw::c_void, + duration_to_seconds(deadline), + ); } } + + pub fn as_ptr(&self) -> *mut v8_sys::IdleTask { + self.0.as_ptr() + } + + pub unsafe fn from_ptr(ptr: *mut v8_sys::IdleTask) -> IdleTask { + IdleTask(ptr::Unique::new(ptr).unwrap()) + } +} + +impl fmt::Debug for IdleTask { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "IdleTask({:?})", unsafe { self.0.as_ref() }) + } } impl Drop for IdleTask { fn drop(&mut self) { unsafe { - v8::v8_IdleTask_Destroy(self.0); + v8_sys::IdleTask_IdleTask_destructor(self.0.as_ptr()); } } } -const PLATFORM_FUNCTIONS: v8::v8_PlatformFunctions = v8::v8_PlatformFunctions { +const PLATFORM_FUNCTIONS: v8_sys::impls::PlatformFunctions = v8_sys::impls::PlatformFunctions { Destroy: Some(destroy_platform), NumberOfAvailableBackgroundThreads: Some(number_of_available_background_threads), CallOnBackgroundThread: Some(call_on_background_thread), @@ -92,55 +145,70 @@ const PLATFORM_FUNCTIONS: v8::v8_PlatformFunctions = v8::v8_PlatformFunctions { MonotonicallyIncreasingTime: Some(monotonically_increasing_time), }; -extern "C" fn destroy_platform() { +extern "C" fn destroy_platform(_this: *mut os::raw::c_void) { // No-op } -extern "C" fn number_of_available_background_threads() -> usize { +extern "C" fn number_of_available_background_threads(_this: *mut os::raw::c_void) -> usize { num_cpus::get() } -extern "C" fn call_on_background_thread(task: v8::TaskPtr, - _expected_runtime: v8::v8_ExpectedRuntime) { - let task = Task(task); - thread::spawn(move || { - unsafe { - v8::v8_Task_Run(task.0); - } +extern "C" fn call_on_background_thread( + _this: *mut os::raw::c_void, + task: *mut v8_sys::Task, + _expected_runtime: v8_sys::Platform_ExpectedRuntime, +) { + let task = unsafe { Task::from_ptr(task) }; + thread::spawn(move || unsafe { + v8_sys::Task_Run(task.0.as_ptr() as *mut os::raw::c_void); }); } -extern "C" fn call_on_foreground_thread(isolate: v8::IsolatePtr, task: v8::TaskPtr) { - let task = Task(task); - let isolate = unsafe { isolate::Isolate::from_raw(isolate) }; +extern "C" fn call_on_foreground_thread( + _this: *mut os::raw::c_void, + isolate: *mut v8_sys::Isolate, + task: *mut v8_sys::Task, +) { + let task = unsafe { Task::from_ptr(task) }; + let isolate = unsafe { isolate::Isolate::from_ptr(isolate) }; isolate.enqueue_task(task); } -extern "C" fn call_delayed_on_foreground_thread(isolate: v8::IsolatePtr, - task: v8::TaskPtr, - delay_in_seconds: f64) { - let task = Task(task); - let isolate = unsafe { isolate::Isolate::from_raw(isolate) }; +extern "C" fn call_delayed_on_foreground_thread( + _this: *mut os::raw::c_void, + isolate: *mut v8_sys::Isolate, + task: *mut v8_sys::Task, + delay_in_seconds: f64, +) { + let task = unsafe { Task::from_ptr(task) }; + let isolate = unsafe { isolate::Isolate::from_ptr(isolate) }; let duration = duration_from_seconds(delay_in_seconds); isolate.enqueue_delayed_task(duration, task); } -extern "C" fn call_idle_on_foreground_thread(isolate: v8::IsolatePtr, idle_task: v8::IdleTaskPtr) { - let idle_task = IdleTask(idle_task); - let isolate = unsafe { isolate::Isolate::from_raw(isolate) }; +extern "C" fn call_idle_on_foreground_thread( + _this: *mut os::raw::c_void, + isolate: *mut v8_sys::Isolate, + idle_task: *mut v8_sys::IdleTask, +) { + let idle_task = unsafe { IdleTask::from_ptr(idle_task) }; + let isolate = unsafe { isolate::Isolate::from_ptr(isolate) }; isolate.enqueue_idle_task(idle_task); } -extern "C" fn idle_tasks_enabled(isolate: v8::IsolatePtr) -> bool { - let isolate = unsafe { isolate::Isolate::from_raw(isolate) }; +extern "C" fn idle_tasks_enabled( + _this: *mut os::raw::c_void, + isolate: *mut v8_sys::Isolate, +) -> bool { + let isolate = unsafe { isolate::Isolate::from_ptr(isolate) }; isolate.supports_idle_tasks() } -extern "C" fn monotonically_increasing_time() -> f64 { +extern "C" fn monotonically_increasing_time(_this: *mut os::raw::c_void) -> f64 { let start = *START_TIME; let d = time::Instant::now().duration_since(start); duration_to_seconds(d) diff --git a/src/template.rs b/src/template.rs index 8dd96aa3..c8ae503b 100644 --- a/src/template.rs +++ b/src/template.rs @@ -1,6 +1,7 @@ //! Templates for constructing functions and objects efficiently. -use v8_sys as v8; +use v8_sys; use isolate; +use handle; use util; use value; use value::Data; @@ -13,7 +14,7 @@ use std::ffi; /// The superclass of object and function templates. #[derive(Debug)] -pub struct Template(isolate::Isolate, v8::TemplateRef); +pub struct Template(v8_sys::Template); /// A FunctionTemplate is used to create functions at runtime. /// @@ -21,37 +22,27 @@ pub struct Template(isolate::Isolate, v8::TemplateRef); /// of a FunctionTemplate after first instantiation will trigger a crash. A FunctionTemplate can /// have properties, these properties are added to the function object when it is created. #[derive(Debug)] -pub struct FunctionTemplate(isolate::Isolate, v8::FunctionTemplateRef); +pub struct FunctionTemplate(v8_sys::FunctionTemplate); /// An ObjectTemplate is used to create objects at runtime. /// /// Properties added to an ObjectTemplate are added to each object created from the ObjectTemplate. #[derive(Debug)] -pub struct ObjectTemplate(isolate::Isolate, v8::ObjectTemplateRef); +pub struct ObjectTemplate(v8_sys::ObjectTemplate); /// A Signature specifies which receiver is valid for a function. #[derive(Debug)] -pub struct Signature(isolate::Isolate, v8::SignatureRef); +pub struct Signature(v8_sys::Signature); impl Signature { /// Creates a new signature. - pub fn new(isolate: &isolate::Isolate) -> Signature { - let raw = unsafe { - util::invoke(isolate, - |c| v8::v8_Signature_New(c, isolate.as_raw(), ptr::null_mut())) - .unwrap() - }; - Signature(isolate.clone(), raw) + pub fn new(isolate: &mut isolate::Isolate) -> handle::Local { + unsafe { handle::Local::new(v8_sys::Signature::New(&mut *isolate, ptr::null_mut())) } } /// Creates a new signature with the specified receiver. - pub fn new_with_receiver(isolate: &isolate::Isolate, receiver: &FunctionTemplate) -> Signature { - let raw = unsafe { - util::invoke(isolate, - |c| v8::v8_Signature_New(c, isolate.as_raw(), receiver.1)) - .unwrap() - }; - Signature(isolate.clone(), raw) + pub fn new_with_receiver(isolate: &mut isolate::Isolate, receiver: handle::Local) -> Signature { + unsafe { handle::Local::new(v8_sys::Signature::New(&mut *isolate, receiver.as_raw())) } } } @@ -72,14 +63,14 @@ impl FunctionTemplate { closure.set_internal_field(0, &callback_ext); util::invoke_ctx(isolate, context, |c| { - v8::v8_FunctionTemplate_New(c, - context.as_raw(), - Some(util::callback), - (&closure as &value::Value).as_raw(), - ptr::null_mut(), - 0, - v8::ConstructorBehavior::ConstructorBehavior_kAllow) - }) + v8_sys::v8_FunctionTemplate_New(c, + context.as_raw(), + Some(util::callback), + (&closure as &value::Value).as_raw(), + ptr::null_mut(), + 0, + v8_sys::ConstructorBehavior::ConstructorBehavior_kAllow) + }) .unwrap() }; FunctionTemplate(isolate.clone(), raw) @@ -89,8 +80,8 @@ impl FunctionTemplate { pub fn get_function(self, context: &context::Context) -> value::Function { unsafe { let raw = util::invoke_ctx(&self.0, context, |c| { - v8::v8_FunctionTemplate_GetFunction(c, self.1, context.as_raw()) - }) + v8_sys::v8_FunctionTemplate_GetFunction(c, self.1, context.as_raw()) + }) .unwrap(); value::Function::from_raw(&self.0, raw) } @@ -102,7 +93,7 @@ impl ObjectTemplate { pub fn new(isolate: &isolate::Isolate) -> ObjectTemplate { let raw = unsafe { util::invoke(isolate, - |c| v8::v8_ObjectTemplate_New(c, isolate.as_raw(), ptr::null_mut())) + |c| v8_sys::v8_ObjectTemplate_New(c, isolate.as_raw(), ptr::null_mut())) .unwrap() }; ObjectTemplate(isolate.clone(), raw) @@ -112,8 +103,8 @@ impl ObjectTemplate { pub fn set_internal_field_count(&self, value: usize) { unsafe { util::invoke(&self.0, |c| { - v8::v8_ObjectTemplate_SetInternalFieldCount(c, self.1, value as os::raw::c_int) - }) + v8_sys::v8_ObjectTemplate_SetInternalFieldCount(c, self.1, value as os::raw::c_int) + }) .unwrap() }; } @@ -123,12 +114,12 @@ impl ObjectTemplate { let template: &Template = self; unsafe { util::invoke(&self.0, |c| { - v8::v8_Template_Set_Raw(c, - template.1, - self.0.as_raw(), - mem::transmute(cname.as_ptr()), - value.as_raw()) - }) + v8_sys::v8_Template_Set_Raw(c, + template.1, + self.0.as_raw(), + mem::transmute(cname.as_ptr()), + value.as_raw()) + }) .unwrap() }; } @@ -137,8 +128,8 @@ impl ObjectTemplate { pub fn new_instance(&self, context: &context::Context) -> value::Object { unsafe { let raw = util::invoke_ctx(&self.0, context, |c| { - v8::v8_ObjectTemplate_NewInstance(c, self.1, context.as_raw()) - }) + v8_sys::v8_ObjectTemplate_NewInstance(c, self.1, context.as_raw()) + }) .unwrap(); value::Object::from_raw(&self.0, raw) } @@ -146,13 +137,13 @@ impl ObjectTemplate { /// Creates an object template from a set of raw pointers. pub unsafe fn from_raw(isolate: &isolate::Isolate, - raw: v8::ObjectTemplateRef) + raw: v8_sys::ObjectTemplateRef) -> ObjectTemplate { ObjectTemplate(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this object template. - pub fn as_raw(&self) -> v8::ObjectTemplateRef { + pub fn as_raw(&self) -> v8_sys::ObjectTemplateRef { self.1 } } @@ -162,11 +153,11 @@ inherit!(ObjectTemplate, Template); inherit!(FunctionTemplate, Template); inherit!(Signature, Data); -reference!(Template, v8::v8_Template_CloneRef, v8::v8_Template_DestroyRef); +reference!(Template, v8_sys::v8_Template_CloneRef, v8_sys::v8_Template_DestroyRef); reference!(FunctionTemplate, - v8::v8_FunctionTemplate_CloneRef, - v8::v8_FunctionTemplate_DestroyRef); + v8_sys::v8_FunctionTemplate_CloneRef, + v8_sys::v8_FunctionTemplate_DestroyRef); reference!(ObjectTemplate, - v8::v8_ObjectTemplate_CloneRef, - v8::v8_ObjectTemplate_DestroyRef); -reference!(Signature, v8::v8_Signature_CloneRef, v8::v8_Signature_DestroyRef); + v8_sys::v8_ObjectTemplate_CloneRef, + v8_sys::v8_ObjectTemplate_DestroyRef); +reference!(Signature, v8_sys::v8_Signature_CloneRef, v8_sys::v8_Signature_DestroyRef); diff --git a/src/util.rs b/src/util.rs index 915b9165..ece086a8 100644 --- a/src/util.rs +++ b/src/util.rs @@ -9,26 +9,34 @@ use std::ptr; use value; pub fn invoke(isolate: &isolate::Isolate, func: F) -> error::Result - where F: FnOnce(v8::RustContext) -> B + where F: FnOnce() -> B { + unimplemented!() + /* invoke_inner(isolate, None, func) + */ } pub fn invoke_ctx(isolate: &isolate::Isolate, context: &context::Context, func: F) -> error::Result - where F: FnOnce(v8::RustContext) -> B + where F: FnOnce() -> B { + unimplemented!() + /* invoke_inner(isolate, Some(context), func) + */ } fn invoke_inner(isolate: &isolate::Isolate, context: Option<&context::Context>, func: F) -> error::Result - where F: FnOnce(v8::RustContext) -> B + where F: FnOnce() -> B { + unimplemented!() + /* let mut exception = ptr::null_mut(); let mut message = ptr::null_mut(); let rust_ctx = v8::RustContext { @@ -74,13 +82,14 @@ fn invoke_inner(isolate: &isolate::Isolate, let stack_trace = message.get_stack_trace().to_captured(); Err(error::ErrorKind::Javascript(message_str, stack_trace).into()) } + */ } -pub extern "C" fn callback(callback_info: v8::FunctionCallbackInfoPtr_Value) { +pub extern "C" fn callback(callback_info: v8::FunctionCallbackInfo) { unsafe { let callback_info = callback_info.as_mut().unwrap(); let isolate = isolate::Isolate::from_raw(callback_info.GetIsolate); - let data = value::Object::from_raw(&isolate, callback_info.Data as v8::ObjectRef); + let data = value::Object::from_raw(&isolate, callback_info.Data as v8::Object); let length = callback_info.Length as isize; let args = (0..length) @@ -120,7 +129,7 @@ pub extern "C" fn callback(callback_info: v8::FunctionCallbackInfoPtr_Value) { fn throw_exception(isolate: &isolate::Isolate, exception: &value::Value) -> value::Value { unsafe { - let raw = v8::v8_Isolate_ThrowException(isolate.as_raw(), exception.as_raw()).as_mut().unwrap(); + let raw = v8::Isolate::ThrowException(isolate.as_raw(), exception.as_raw()).as_mut().unwrap(); ::value::Value::from_raw(isolate, raw) } } @@ -128,6 +137,8 @@ fn throw_exception(isolate: &isolate::Isolate, exception: &value::Value) -> valu fn create_panic_error(isolate: &isolate::Isolate, panic: Box) -> value::Value { + unimplemented!() + /* let context = isolate.current_context() .unwrap_or_else(|| context::Context::new(&isolate)); let message = if let Some(s) = panic.downcast_ref::() { @@ -143,6 +154,7 @@ fn create_panic_error(isolate: &isolate::Isolate, exception.set(&context, &panic_info_key, &panic_info); exception.into() + */ } macro_rules! reference { diff --git a/src/value.rs b/src/value.rs index 3041580a..87ed907c 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,5 +1,5 @@ //! Javascript values that user code can interact with. -use v8_sys as v8; +use v8_sys; use context; use error; use isolate; @@ -12,203 +12,203 @@ use template; /// The superclass of values and API object templates. #[derive(Debug)] -pub struct Data(isolate::Isolate, v8::DataRef); +pub struct Data(v8_sys::Data); /// The superclass of all JavaScript values and objects. #[derive(Debug)] -pub struct Value(isolate::Isolate, v8::ValueRef); +pub struct Value(v8_sys::Value); /// The superclass of primitive values. See ECMA-262 4.3.2. #[derive(Debug)] -pub struct Primitive(isolate::Isolate, v8::PrimitiveRef); +pub struct Primitive(v8_sys::Primitive); /// A primitive boolean value (ECMA-262, 4.3.14). Either the true or false value. #[derive(Debug)] -pub struct Boolean(isolate::Isolate, v8::BooleanRef); +pub struct Boolean(v8_sys::Boolean); /// A superclass for symbols and strings. #[derive(Debug)] -pub struct Name(isolate::Isolate, v8::NameRef); +pub struct Name(v8_sys::Name); /// A JavaScript string value (ECMA-262, 4.3.17). #[derive(Debug)] -pub struct String(isolate::Isolate, v8::StringRef); +pub struct String(v8_sys::String); /// A JavaScript symbol (ECMA-262 edition 6) /// /// This is an experimental feature. Use at your own risk. #[derive(Debug)] -pub struct Symbol(isolate::Isolate, v8::SymbolRef); +pub struct Symbol(v8_sys::Symbol); /// A private symbol /// /// This is an experimental feature. Use at your own risk. #[derive(Debug)] -pub struct Private(isolate::Isolate, v8::PrivateRef); +pub struct Private(v8_sys::Private); /// A JavaScript number value (ECMA-262, 4.3.20) #[derive(Debug)] -pub struct Number(isolate::Isolate, v8::NumberRef); +pub struct Number(v8_sys::Number); /// A JavaScript value representing a signed integer. #[derive(Debug)] -pub struct Integer(isolate::Isolate, v8::IntegerRef); +pub struct Integer(v8_sys::Integer); /// A JavaScript value representing a 32-bit signed integer. #[derive(Debug)] -pub struct Int32(isolate::Isolate, v8::Int32Ref); +pub struct Int32(v8_sys::Int32); /// A JavaScript value representing a 32-bit unsigned integer. #[derive(Debug)] -pub struct Uint32(isolate::Isolate, v8::Uint32Ref); +pub struct Uint32(v8_sys::Uint32); /// A JavaScript object (ECMA-262, 4.3.3) #[derive(Debug)] -pub struct Object(isolate::Isolate, v8::ObjectRef); +pub struct Object(v8_sys::Object); /// An instance of the built-in array constructor (ECMA-262, 15.4.2). #[derive(Debug)] -pub struct Array(isolate::Isolate, v8::ArrayRef); +pub struct Array(v8_sys::Array); /// An instance of the built-in Map constructor (ECMA-262, 6th Edition, 23.1.1). #[derive(Debug)] -pub struct Map(isolate::Isolate, v8::MapRef); +pub struct Map(v8_sys::Map); /// An instance of the built-in Set constructor (ECMA-262, 6th Edition, 23.2.1). #[derive(Debug)] -pub struct Set(isolate::Isolate, v8::SetRef); +pub struct Set(v8_sys::Set); /// A JavaScript function object (ECMA-262, 15.3). #[derive(Debug)] -pub struct Function(isolate::Isolate, v8::FunctionRef); +pub struct Function(v8_sys::Function); /// An instance of the built-in Promise constructor (ES6 draft). /// /// This API is experimental. Only works with --harmony flag. #[derive(Debug)] -pub struct Promise(isolate::Isolate, v8::PromiseRef); +pub struct Promise(v8_sys::Promise); /// An instance of the built-in Proxy constructor (ECMA-262, 6th Edition, 26.2.1). #[derive(Debug)] -pub struct Proxy(isolate::Isolate, v8::ProxyRef); +pub struct Proxy(v8_sys::Proxy); /// An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct ArrayBuffer(isolate::Isolate, v8::ArrayBufferRef); +pub struct ArrayBuffer(v8_sys::ArrayBuffer); /// A base class for an instance of one of "views" over ArrayBuffer, including TypedArrays and /// DataView (ES6 draft 15.13). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct ArrayBufferView(isolate::Isolate, v8::ArrayBufferViewRef); +pub struct ArrayBufferView(v8_sys::ArrayBufferView); /// A base class for an instance of TypedArray series of constructors (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct TypedArray(isolate::Isolate, v8::TypedArrayRef); +pub struct TypedArray(v8_sys::TypedArray); /// An instance of Uint8Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Uint8Array(isolate::Isolate, v8::Uint8ArrayRef); +pub struct Uint8Array(v8_sys::Uint8Array); /// An instance of Uint8ClampedArray constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Uint8ClampedArray(isolate::Isolate, v8::Uint8ClampedArrayRef); +pub struct Uint8ClampedArray(v8_sys::Uint8ClampedArray); /// An instance of Int8Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Int8Array(isolate::Isolate, v8::Int8ArrayRef); +pub struct Int8Array(v8_sys::Int8Array); /// An instance of Uint16Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Uint16Array(isolate::Isolate, v8::Uint16ArrayRef); +pub struct Uint16Array(v8_sys::Uint16Array); /// An instance of Int16Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Int16Array(isolate::Isolate, v8::Int16ArrayRef); +pub struct Int16Array(v8_sys::Int16Array); /// An instance of Uint32Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Uint32Array(isolate::Isolate, v8::Uint32ArrayRef); +pub struct Uint32Array(v8_sys::Uint32Array); /// An instance of Int32Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Int32Array(isolate::Isolate, v8::Int32ArrayRef); +pub struct Int32Array(v8_sys::Int32Array); /// An instance of Float32Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Float32Array(isolate::Isolate, v8::Float32ArrayRef); +pub struct Float32Array(v8_sys::Float32Array); /// An instance of Float64Array constructor (ES6 draft 15.13.6). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct Float64Array(isolate::Isolate, v8::Float64ArrayRef); +pub struct Float64Array(v8_sys::Float64Array); /// An instance of DataView constructor (ES6 draft 15.13.7). /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct DataView(isolate::Isolate, v8::DataViewRef); +pub struct DataView(v8_sys::DataView); /// An instance of the built-in SharedArrayBuffer constructor. /// /// This API is experimental and may change significantly. #[derive(Debug)] -pub struct SharedArrayBuffer(isolate::Isolate, v8::SharedArrayBufferRef); +pub struct SharedArrayBuffer(v8_sys::SharedArrayBuffer); /// An instance of the built-in Date constructor (ECMA-262, 15.9). #[derive(Debug)] -pub struct Date(isolate::Isolate, v8::DateRef); +pub struct Date(v8_sys::Date); /// A Number object (ECMA-262, 4.3.21). #[derive(Debug)] -pub struct NumberObject(isolate::Isolate, v8::NumberObjectRef); +pub struct NumberObject(v8_sys::NumberObject); /// A Boolean object (ECMA-262, 4.3.15). #[derive(Debug)] -pub struct BooleanObject(isolate::Isolate, v8::BooleanObjectRef); +pub struct BooleanObject(v8_sys::BooleanObject); /// A String object (ECMA-262, 4.3.18). #[derive(Debug)] -pub struct StringObject(isolate::Isolate, v8::StringObjectRef); +pub struct StringObject(v8_sys::StringObject); /// A Symbol object (ECMA-262 edition 6). /// /// This is an experimental feature. Use at your own risk. #[derive(Debug)] -pub struct SymbolObject(isolate::Isolate, v8::SymbolObjectRef); +pub struct SymbolObject(v8_sys::SymbolObject); /// An instance of the built-in RegExp constructor (ECMA-262, 15.10). #[derive(Debug)] -pub struct RegExp(isolate::Isolate, v8::RegExpRef); +pub struct RegExp(v8_sys::RegExp); /// A JavaScript value that wraps an external value. This type of value is mainly used to associate /// native data structures with JavaScript objects. #[derive(Debug)] -pub struct External(isolate::Isolate, v8::ExternalRef); +pub struct External(v8_sys::External); -pub struct Exception(isolate::Isolate, v8::ExceptionRef); +pub struct Exception(v8_sys::Exception); pub struct PropertyCallbackInfo { pub this: Object, @@ -228,22 +228,22 @@ pub struct FunctionCallbackInfo { pub type FunctionCallback = Fn(FunctionCallbackInfo) -> Result + 'static; pub fn undefined(isolate: &isolate::Isolate) -> Primitive { - let raw = unsafe { util::invoke(isolate, |c| v8::v8_Undefined(c)).unwrap() }; + let raw = unsafe { util::invoke(isolate, |c| v8_sys::v8_Undefined(c)).unwrap() }; Primitive(isolate.clone(), raw) } pub fn null(isolate: &isolate::Isolate) -> Primitive { - let raw = unsafe { util::invoke(isolate, |c| v8::v8_Null(c)).unwrap() }; + let raw = unsafe { util::invoke(isolate, |c| v8_sys::v8_Null(c)).unwrap() }; Primitive(isolate.clone(), raw) } pub fn true_(isolate: &isolate::Isolate) -> Boolean { - let raw = unsafe { util::invoke(isolate, |c| v8::v8_True(c)).unwrap() }; + let raw = unsafe { util::invoke(isolate, |c| v8_sys::v8_True(c)).unwrap() }; Boolean(isolate.clone(), raw) } pub fn false_(isolate: &isolate::Isolate) -> Boolean { - let raw = unsafe { util::invoke(isolate, |c| v8::v8_False(c)).unwrap() }; + let raw = unsafe { util::invoke(isolate, |c| v8_sys::v8_False(c)).unwrap() }; Boolean(isolate.clone(), raw) } @@ -297,12 +297,12 @@ macro_rules! partial_get { impl Data { /// Creates a data from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::DataRef) -> Data { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::DataRef) -> Data { Data(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this primitive. - pub fn as_raw(&self) -> v8::DataRef { + pub fn as_raw(&self) -> v8_sys::DataRef { self.1 } } @@ -310,274 +310,274 @@ impl Data { impl Value { downcast!(is_undefined, "Returns true if this value is the undefined value. See ECMA-262 4.3.10.", - v8::v8_Value_IsUndefined); + v8_sys::v8_Value_IsUndefined); downcast!(is_null, "Returns true if this value is the null value. See ECMA-262 4.3.11.", - v8::v8_Value_IsNull); + v8_sys::v8_Value_IsNull); downcast!(is_true, "Returns true if this value is true.", - v8::v8_Value_IsTrue); + v8_sys::v8_Value_IsTrue); downcast!(is_false, "Returns true if this value is false.", - v8::v8_Value_IsFalse); + v8_sys::v8_Value_IsFalse); downcast!(is_name, "Returns true if this value is a symbol or a string.\n\nThis is an experimental \ feature.", into_name, "", - v8::v8_Value_IsName, + v8_sys::v8_Value_IsName, Name); downcast!(is_string, "Returns true if this value is an instance of the String type. See ECMA-262 8.4.", into_string, "", - v8::v8_Value_IsString, + v8_sys::v8_Value_IsString, String); downcast!(is_symbol, "Returns true if this value is a symbol.\n\nThis is an experimental feature.", into_symbol, "", - v8::v8_Value_IsSymbol, + v8_sys::v8_Value_IsSymbol, Symbol); downcast!(is_function, "Returns true if this value is a function.", into_function, "", - v8::v8_Value_IsFunction, + v8_sys::v8_Value_IsFunction, Function); downcast!(is_array, "Returns true if this value is an array. Note that it will return false for an \ Proxy for an array.", into_array, "", - v8::v8_Value_IsArray, + v8_sys::v8_Value_IsArray, Array); downcast!(is_object, "Returns true if this value is an object.", into_object, "", - v8::v8_Value_IsObject, + v8_sys::v8_Value_IsObject, Object); downcast!(is_boolean, "Returns true if this value is boolean.", into_boolean, "", - v8::v8_Value_IsBoolean, + v8_sys::v8_Value_IsBoolean, Boolean); downcast!(is_number, "Returns true if this value is a number.", into_number, "", - v8::v8_Value_IsNumber, + v8_sys::v8_Value_IsNumber, Number); downcast!(is_external, "Returns true if this value is external.", into_external, "", - v8::v8_Value_IsExternal, + v8_sys::v8_Value_IsExternal, External); downcast!(is_int32, "Returns true if this value is a 32-bit signed integer.", into_int32, "", - v8::v8_Value_IsInt32, + v8_sys::v8_Value_IsInt32, Int32); downcast!(is_uint32, "Returns true if this value is a 32-bit unsigned integer.", into_uint32, "", - v8::v8_Value_IsUint32, + v8_sys::v8_Value_IsUint32, Uint32); downcast!(is_date, "Returns true if this value is a Date.", into_date, "", - v8::v8_Value_IsDate, + v8_sys::v8_Value_IsDate, Date); downcast!(is_arguments_object, "Returns true if this value is an Arguments object.", - v8::v8_Value_IsArgumentsObject); + v8_sys::v8_Value_IsArgumentsObject); downcast!(is_boolean_object, "Returns true if this value is a Boolean object.", into_boolean_object, "", - v8::v8_Value_IsBooleanObject, + v8_sys::v8_Value_IsBooleanObject, BooleanObject); downcast!(is_number_object, "Returns true if this value is a Number object.", into_number_object, "", - v8::v8_Value_IsNumberObject, + v8_sys::v8_Value_IsNumberObject, NumberObject); downcast!(is_string_object, "Returns true if this value is a String object.", into_string_object, "", - v8::v8_Value_IsStringObject, + v8_sys::v8_Value_IsStringObject, StringObject); downcast!(is_symbol_object, "Returns true if this value is a Symbol object.\n\nThis is an experimental feature.", into_symbol_object, "", - v8::v8_Value_IsSymbolObject, + v8_sys::v8_Value_IsSymbolObject, Symbol); downcast!(is_native_error, "Returns true if this value is a NativeError.", - v8::v8_Value_IsNativeError); + v8_sys::v8_Value_IsNativeError); downcast!(is_reg_exp, "Returns true if this value is a RegExp.", into_reg_exp, "", - v8::v8_Value_IsRegExp, + v8_sys::v8_Value_IsRegExp, RegExp); downcast!(is_generator_function, "Returns true if this value is a Generator function.\n\nThis is an experimental \ feature.", - v8::v8_Value_IsGeneratorFunction); + v8_sys::v8_Value_IsGeneratorFunction); downcast!(is_generator_object, "Returns true if this value is a Generator object (iterator).\n\nThis is an \ experimental feature.", - v8::v8_Value_IsGeneratorObject); + v8_sys::v8_Value_IsGeneratorObject); downcast!(is_promise, "Returns true if this value is a Promise.\n\nThis is an experimental feature.", into_promise, "", - v8::v8_Value_IsPromise, + v8_sys::v8_Value_IsPromise, Promise); downcast!(is_map, "Returns true if this value is a Map.", into_map, "", - v8::v8_Value_IsMap, + v8_sys::v8_Value_IsMap, Map); downcast!(is_set, "Returns true if this value is a Set.", into_set, "", - v8::v8_Value_IsSet, + v8_sys::v8_Value_IsSet, Set); downcast!(is_map_iterator, "Returns true if this value is a Map Iterator.", - v8::v8_Value_IsMapIterator); + v8_sys::v8_Value_IsMapIterator); downcast!(is_set_iterator, "Returns true if this value is a Set Iterator.", - v8::v8_Value_IsSetIterator); + v8_sys::v8_Value_IsSetIterator); downcast!(is_weak_map, "Returns true if this value is a WeakMap.", - v8::v8_Value_IsWeakMap); + v8_sys::v8_Value_IsWeakMap); downcast!(is_weak_set, "Returns true if this value is a WeakSet.", - v8::v8_Value_IsWeakSet); + v8_sys::v8_Value_IsWeakSet); downcast!(is_array_buffer, "Returns true if this value is an ArrayBuffer.\n\nThis is an experimental feature.", into_array_buffer, "", - v8::v8_Value_IsArrayBuffer, + v8_sys::v8_Value_IsArrayBuffer, ArrayBuffer); downcast!(is_array_buffer_view, "Returns true if this value is an ArrayBufferView.\n\nThis is an experimental \ feature.", into_array_buffer_view, "", - v8::v8_Value_IsArrayBufferView, + v8_sys::v8_Value_IsArrayBufferView, ArrayBufferView); downcast!(is_typed_array, "Returns true if this value is one of TypedArrays.\n\nThis is an experimental \ feature.", into_typed_array, "", - v8::v8_Value_IsTypedArray, + v8_sys::v8_Value_IsTypedArray, TypedArray); downcast!(is_uint8_array, "Returns true if this value is an Uint8Array.\n\nThis is an experimental feature.", into_uint8_array, "", - v8::v8_Value_IsUint8Array, + v8_sys::v8_Value_IsUint8Array, Uint8Array); downcast!(is_uint8_clamped_array, "Returns true if this value is an Uint8ClampedArray.\n\nThis is an experimental \ feature.", into_uint8_clamped_array, "", - v8::v8_Value_IsUint8ClampedArray, + v8_sys::v8_Value_IsUint8ClampedArray, Uint8ClampedArray); downcast!(is_int8_array, "Returns true if this value is an Int8Array.\n\nThis is an experimental feature.", into_int8_array, "", - v8::v8_Value_IsInt8Array, + v8_sys::v8_Value_IsInt8Array, Int8Array); downcast!(is_uint16_array, "Returns true if this value is an Uint16Array.\n\nThis is an experimental feature.", into_uint16_array, "", - v8::v8_Value_IsUint16Array, + v8_sys::v8_Value_IsUint16Array, Uint16Array); downcast!(is_int16_array, "Returns true if this value is an Int16Array.\n\nThis is an experimental feature.", into_int16_array, "", - v8::v8_Value_IsInt16Array, + v8_sys::v8_Value_IsInt16Array, Int16Array); downcast!(is_uint32_array, "Returns true if this value is an Uint32Array.\n\nThis is an experimental feature.", into_uint32_array, "", - v8::v8_Value_IsUint32Array, + v8_sys::v8_Value_IsUint32Array, Uint32Array); downcast!(is_int32_array, "Returns true if this value is an Int32Array.\n\nThis is an experimental feature.", into_int32_array, "", - v8::v8_Value_IsInt32Array, + v8_sys::v8_Value_IsInt32Array, Int32Array); downcast!(is_float32_array, "Returns true if this value is a Float32Array.\n\nThis is an experimental feature.", into_float32_array, "", - v8::v8_Value_IsFloat32Array, + v8_sys::v8_Value_IsFloat32Array, Float32Array); downcast!(is_float64_array, "Returns true if this value is a Float64Array.\n\nThis is an experimental feature.", into_float64_array, "", - v8::v8_Value_IsFloat64Array, + v8_sys::v8_Value_IsFloat64Array, Float64Array); downcast!(is_data_view, "Returns true if this value is a DataView.\n\nThis is an experimental feature.", into_data_view, "", - v8::v8_Value_IsDataView, + v8_sys::v8_Value_IsDataView, DataView); downcast!(is_shared_array_buffer, "Returns true if this value is a SharedArrayBuffer.\n\nThis is an experimental \ feature.", into_shared_array_buffer, "", - v8::v8_Value_IsSharedArrayBuffer, + v8_sys::v8_Value_IsSharedArrayBuffer, SharedArrayBuffer); downcast!(is_proxy, "Returns true if this value is a JavaScript Proxy.", into_proxy, "", - v8::v8_Value_IsProxy, + v8_sys::v8_Value_IsProxy, Proxy); - partial_conversion!(to_boolean, v8::v8_Value_ToBoolean, Boolean); - partial_conversion!(to_number, v8::v8_Value_ToNumber, Number); - partial_conversion!(to_string, v8::v8_Value_ToString, String); - partial_conversion!(to_detail_string, v8::v8_Value_ToDetailString, String); - partial_conversion!(to_object, v8::v8_Value_ToObject, Object); - partial_conversion!(to_integer, v8::v8_Value_ToInteger, Integer); - partial_conversion!(to_uint32, v8::v8_Value_ToUint32, Uint32); - partial_conversion!(to_int32, v8::v8_Value_ToInt32, Int32); - partial_conversion!(to_array_index, v8::v8_Value_ToArrayIndex, Uint32); + partial_conversion!(to_boolean, v8_sys::v8_Value_ToBoolean, Boolean); + partial_conversion!(to_number, v8_sys::v8_Value_ToNumber, Number); + partial_conversion!(to_string, v8_sys::v8_Value_ToString, String); + partial_conversion!(to_detail_string, v8_sys::v8_Value_ToDetailString, String); + partial_conversion!(to_object, v8_sys::v8_Value_ToObject, Object); + partial_conversion!(to_integer, v8_sys::v8_Value_ToInteger, Integer); + partial_conversion!(to_uint32, v8_sys::v8_Value_ToUint32, Uint32); + partial_conversion!(to_int32, v8_sys::v8_Value_ToInt32, Int32); + partial_conversion!(to_array_index, v8_sys::v8_Value_ToArrayIndex, Uint32); pub fn boolean_value(&self, context: &context::Context) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, - |i| v8::v8_Value_BooleanValue(i, self.1, context.as_raw())) + |i| v8_sys::v8_Value_BooleanValue(i, self.1, context.as_raw())) .unwrap(); assert!( m.is_set); @@ -585,15 +585,15 @@ impl Value { } } - partial_get!(number_value, v8::v8_Value_NumberValue, f64); - partial_get!(integer_value, v8::v8_Value_IntegerValue, i64); - partial_get!(uint32_value, v8::v8_Value_Uint32Value, u32); - partial_get!(int32_value, v8::v8_Value_Int32Value, i32); + partial_get!(number_value, v8_sys::v8_Value_NumberValue, f64); + partial_get!(integer_value, v8_sys::v8_Value_IntegerValue, i64); + partial_get!(uint32_value, v8_sys::v8_Value_Uint32Value, u32); + partial_get!(int32_value, v8_sys::v8_Value_Int32Value, i32); pub fn equals(&self, context: &context::Context, that: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Value_Equals(c, self.1, context.as_raw(), that.as_raw()) + v8_sys::v8_Value_Equals(c, self.1, context.as_raw(), that.as_raw()) }) .unwrap(); assert!( m.is_set); @@ -604,23 +604,23 @@ impl Value { pub fn strict_equals(&self, that: &Value) -> bool { unsafe { - util::invoke(&self.0, |c| v8::v8_Value_StrictEquals(c, self.1, that.as_raw())).unwrap() + util::invoke(&self.0, |c| v8_sys::v8_Value_StrictEquals(c, self.1, that.as_raw())).unwrap() } } pub fn same_value(&self, that: &Value) -> bool { unsafe { - util::invoke(&self.0, |c| v8::v8_Value_SameValue(c, self.1, that.as_raw())).unwrap() + util::invoke(&self.0, |c| v8_sys::v8_Value_SameValue(c, self.1, that.as_raw())).unwrap() } } /// Creates a value from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::ValueRef) -> Value { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::ValueRef) -> Value { Value(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this value. - pub fn as_raw(&self) -> v8::ValueRef { + pub fn as_raw(&self) -> v8_sys::ValueRef { self.1 } } @@ -633,12 +633,12 @@ impl PartialEq for Value { impl Primitive { /// Creates a primitive from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::PrimitiveRef) -> Primitive { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::PrimitiveRef) -> Primitive { Primitive(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this primitive. - pub fn as_raw(&self) -> v8::PrimitiveRef { + pub fn as_raw(&self) -> v8_sys::PrimitiveRef { self.1 } } @@ -646,22 +646,22 @@ impl Primitive { impl Boolean { pub fn new(isolate: &isolate::Isolate, value: bool) -> Boolean { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Boolean_New(c, isolate.as_raw(), value)).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Boolean_New(c, isolate.as_raw(), value)).unwrap() }; Boolean(isolate.clone(), raw) } pub fn value(&self) -> bool { - unsafe { util::invoke(&self.0, |c| v8::v8_Boolean_Value(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Boolean_Value(c, self.1)).unwrap() } } /// Creates a boolean from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::BooleanRef) -> Boolean { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::BooleanRef) -> Boolean { Boolean(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this boolean. - pub fn as_raw(&self) -> v8::BooleanRef { + pub fn as_raw(&self) -> v8_sys::BooleanRef { self.1 } } @@ -675,16 +675,16 @@ impl Name { /// The return value will never be 0. Also, it is not guaranteed /// to be unique. pub fn get_identity_hash(&self) -> u32 { - unsafe { util::invoke(&self.0, |c| v8::v8_Name_GetIdentityHash(c, self.1)).unwrap() as u32 } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Name_GetIdentityHash(c, self.1)).unwrap() as u32 } } /// Creates a name from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::NameRef) -> Name { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::NameRef) -> Name { Name(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this primitive. - pub fn as_raw(&self) -> v8::NameRef { + pub fn as_raw(&self) -> v8_sys::NameRef { self.1 } } @@ -692,7 +692,7 @@ impl Name { impl String { pub fn empty(isolate: &isolate::Isolate) -> String { let raw = - unsafe { util::invoke(&isolate, |c| v8::v8_String_Empty(c, isolate.as_raw())).unwrap() }; + unsafe { util::invoke(&isolate, |c| v8_sys::v8_String_Empty(c, isolate.as_raw())).unwrap() }; String(isolate.clone(), raw) } @@ -701,7 +701,7 @@ impl String { let raw = unsafe { let ptr = mem::transmute(str.as_ptr()); let len = str.len() as os::raw::c_int; - util::invoke(&isolate, |c| v8::v8_String_NewFromUtf8_Normal(c, ptr, len)).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_String_NewFromUtf8_Normal(c, ptr, len)).unwrap() }; String(isolate.clone(), raw) } @@ -712,7 +712,7 @@ impl String { let ptr = mem::transmute(str.as_ptr()); let len = str.len() as os::raw::c_int; let raw = util::invoke(&isolate, - |c| v8::v8_String_NewFromUtf8_Internalized(c, ptr, len)) + |c| v8_sys::v8_String_NewFromUtf8_Internalized(c, ptr, len)) .unwrap(); String(isolate.clone(), raw) } @@ -720,12 +720,12 @@ impl String { /// Returns the number of characters in this string. pub fn length(&self) -> u32 { - unsafe { util::invoke(&self.0, |c| v8::v8_String_Length(c, self.1)).unwrap() as u32 } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_String_Length(c, self.1)).unwrap() as u32 } } /// Returns the number of bytes in the UTF-8 encoded representation of this string. pub fn utf8_length(&self) -> u32 { - unsafe { util::invoke(&self.0, |c| v8::v8_String_Utf8Length(c, self.1)).unwrap() as u32 } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_String_Utf8Length(c, self.1)).unwrap() as u32 } } /// Returns whether this string is known to contain only one byte data. @@ -734,7 +734,7 @@ impl String { /// /// False negatives are possible. pub fn is_one_byte(&self) -> bool { - unsafe { util::invoke(&self.0, |c| v8::v8_String_IsOneByte(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_String_IsOneByte(c, self.1)).unwrap() } } /// Returns whether this string contain only one byte data. @@ -742,20 +742,20 @@ impl String { /// Will read the entire string in some cases. pub fn contains_only_one_byte(&self) -> bool { unsafe { - util::invoke(&self.0, |c| v8::v8_String_ContainsOnlyOneByte(c, self.1)).unwrap() + util::invoke(&self.0, |c| v8_sys::v8_String_ContainsOnlyOneByte(c, self.1)).unwrap() } } pub fn value(&self) -> ::std::string::String { let len = unsafe { - util::invoke(&self.0, |c| v8::v8_String_Utf8Length(c, self.1)).unwrap() + util::invoke(&self.0, |c| v8_sys::v8_String_Utf8Length(c, self.1)).unwrap() } as usize; let mut buf = vec![0u8; len]; unsafe { let ptr = mem::transmute(buf.as_mut_ptr()); util::invoke(&self.0, |c| { - v8::v8_String_WriteUtf8(c, self.1, ptr, len as i32) + v8_sys::v8_String_WriteUtf8(c, self.1, ptr, len as i32) }) .unwrap(); ::std::string::String::from_utf8_unchecked(buf) @@ -763,12 +763,12 @@ impl String { } /// Creates a string from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::StringRef) -> String { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::StringRef) -> String { String(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this string. - pub fn as_raw(&self) -> v8::StringRef { + pub fn as_raw(&self) -> v8_sys::StringRef { self.1 } } @@ -782,7 +782,7 @@ impl Symbol { pub fn for_name(isolate: &isolate::Isolate, name: &String) -> Symbol { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Symbol_For(c, isolate.as_raw(), name.as_raw())) + |c| v8_sys::v8_Symbol_For(c, isolate.as_raw(), name.as_raw())) .unwrap() }; Symbol(isolate.clone(), raw) @@ -795,7 +795,7 @@ impl Symbol { pub fn for_api_name(isolate: &isolate::Isolate, name: &String) -> Symbol { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Symbol_ForApi(c, isolate.as_raw(), name.as_raw())) + |c| v8_sys::v8_Symbol_ForApi(c, isolate.as_raw(), name.as_raw())) .unwrap() }; Symbol(isolate.clone(), raw) @@ -804,7 +804,7 @@ impl Symbol { /// Well-known symbol `Symbol.iterator`. pub fn get_iterator(isolate: &isolate::Isolate) -> Symbol { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Symbol_GetIterator(c, isolate.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Symbol_GetIterator(c, isolate.as_raw())).unwrap() }; Symbol(isolate.clone(), raw) } @@ -812,7 +812,7 @@ impl Symbol { /// Well-known symbol `Symbol.unscopables`. pub fn get_unscopables(isolate: &isolate::Isolate) -> Symbol { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Symbol_GetUnscopables(c, isolate.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Symbol_GetUnscopables(c, isolate.as_raw())).unwrap() }; Symbol(isolate.clone(), raw) } @@ -820,7 +820,7 @@ impl Symbol { /// Well-known symbol `Symbol.toStringTag`. pub fn get_to_string_tag(isolate: &isolate::Isolate) -> Symbol { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Symbol_GetToStringTag(c, isolate.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Symbol_GetToStringTag(c, isolate.as_raw())).unwrap() }; Symbol(isolate.clone(), raw) } @@ -829,19 +829,19 @@ impl Symbol { pub fn get_is_concat_spreadable(isolate: &isolate::Isolate) -> Symbol { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Symbol_GetIsConcatSpreadable(c, isolate.as_raw())) + |c| v8_sys::v8_Symbol_GetIsConcatSpreadable(c, isolate.as_raw())) .unwrap() }; Symbol(isolate.clone(), raw) } /// Creates a symbol from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::SymbolRef) -> Symbol { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::SymbolRef) -> Symbol { Symbol(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this symbol. - pub fn as_raw(&self) -> v8::SymbolRef { + pub fn as_raw(&self) -> v8_sys::SymbolRef { self.1 } } @@ -853,7 +853,7 @@ impl Private { pub fn new(isolate: &isolate::Isolate, name: &String) -> Private { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Private_New(c, isolate.as_raw(), name.as_raw())) + |c| v8_sys::v8_Private_New(c, isolate.as_raw(), name.as_raw())) .unwrap() }; Private(isolate.clone(), raw) @@ -869,19 +869,19 @@ impl Private { pub fn for_api_name(isolate: &isolate::Isolate, name: &String) -> Private { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Private_ForApi(c, isolate.as_raw(), name.as_raw())) + |c| v8_sys::v8_Private_ForApi(c, isolate.as_raw(), name.as_raw())) .unwrap() }; Private(isolate.clone(), raw) } /// Creates a private from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::PrivateRef) -> Private { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::PrivateRef) -> Private { Private(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this private. - pub fn as_raw(&self) -> v8::PrivateRef { + pub fn as_raw(&self) -> v8_sys::PrivateRef { self.1 } } @@ -889,22 +889,22 @@ impl Private { impl Number { pub fn new(isolate: &isolate::Isolate, value: f64) -> Number { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Number_New(c, isolate.as_raw(), value)).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Number_New(c, isolate.as_raw(), value)).unwrap() }; Number(isolate.clone(), raw) } pub fn value(&self) -> f64 { - unsafe { util::invoke(&self.0, |c| v8::v8_Number_Value(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Number_Value(c, self.1)).unwrap() } } /// Creates a number from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::NumberRef) -> Number { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::NumberRef) -> Number { Number(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this number. - pub fn as_raw(&self) -> v8::NumberRef { + pub fn as_raw(&self) -> v8_sys::NumberRef { self.1 } } @@ -912,7 +912,7 @@ impl Number { impl Integer { pub fn new(isolate: &isolate::Isolate, value: i32) -> Integer { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Integer_New(c, isolate.as_raw(), value)).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Integer_New(c, isolate.as_raw(), value)).unwrap() }; Integer(isolate.clone(), raw) } @@ -920,55 +920,55 @@ impl Integer { pub fn new_from_unsigned(isolate: &isolate::Isolate, value: u32) -> Integer { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Integer_NewFromUnsigned(c, isolate.as_raw(), value)) + |c| v8_sys::v8_Integer_NewFromUnsigned(c, isolate.as_raw(), value)) .unwrap() }; Integer(isolate.clone(), raw) } pub fn value(&self) -> i64 { - unsafe { util::invoke(&self.0, |c| v8::v8_Integer_Value(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Integer_Value(c, self.1)).unwrap() } } /// Creates an integer from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::IntegerRef) -> Integer { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::IntegerRef) -> Integer { Integer(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this integer. - pub fn as_raw(&self) -> v8::IntegerRef { + pub fn as_raw(&self) -> v8_sys::IntegerRef { self.1 } } impl Int32 { pub fn value(&self) -> i32 { - unsafe { util::invoke(&self.0, |c| v8::v8_Int32_Value(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Int32_Value(c, self.1)).unwrap() } } /// Creates a 32-bit integer from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::Int32Ref) -> Int32 { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::Int32Ref) -> Int32 { Int32(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this 32-bit integer. - pub fn as_raw(&self) -> v8::Int32Ref { + pub fn as_raw(&self) -> v8_sys::Int32Ref { self.1 } } impl Uint32 { pub fn value(&self) -> u32 { - unsafe { util::invoke(&self.0, |c| v8::v8_Uint32_Value(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Uint32_Value(c, self.1)).unwrap() } } /// Creates a 32-bit unsigned integer from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::Uint32Ref) -> Uint32 { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::Uint32Ref) -> Uint32 { Uint32(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this 32-bit unsigned integer. - pub fn as_raw(&self) -> v8::Uint32Ref { + pub fn as_raw(&self) -> v8_sys::Uint32Ref { self.1 } } @@ -977,7 +977,7 @@ impl Object { pub fn new(isolate: &isolate::Isolate, context: &context::Context) -> Object { let _g = context.make_current(); let raw = unsafe { - util::invoke_ctx(&isolate, context, |c| v8::v8_Object_New(c, isolate.as_raw())).unwrap() + util::invoke_ctx(&isolate, context, |c| v8_sys::v8_Object_New(c, isolate.as_raw())).unwrap() }; Object(isolate.clone(), raw) } @@ -985,7 +985,7 @@ impl Object { pub fn set(&self, context: &context::Context, key: &Value, value: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_Set_Key(c, self.1, context.as_raw(), key.as_raw(), value.as_raw()) + v8_sys::v8_Object_Set_Key(c, self.1, context.as_raw(), key.as_raw(), value.as_raw()) }) .unwrap(); @@ -997,7 +997,7 @@ impl Object { pub fn set_index(&self, context: &context::Context, index: u32, value: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_Set_Index(c, self.1, context.as_raw(), index, value.as_raw()) + v8_sys::v8_Object_Set_Index(c, self.1, context.as_raw(), index, value.as_raw()) }) .unwrap(); @@ -1013,7 +1013,7 @@ impl Object { -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_CreateDataProperty_Key(c, + v8_sys::v8_Object_CreateDataProperty_Key(c, self.1, context.as_raw(), key.as_raw(), @@ -1033,7 +1033,7 @@ impl Object { -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_CreateDataProperty_Index(c, + v8_sys::v8_Object_CreateDataProperty_Index(c, self.1, context.as_raw(), index, @@ -1050,7 +1050,7 @@ impl Object { unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_Get_Key(c, self.1, context.as_raw(), key.as_raw())) + |c| v8_sys::v8_Object_Get_Key(c, self.1, context.as_raw(), key.as_raw())) .map(|p| Value(self.0.clone(), p)) .unwrap() } @@ -1060,7 +1060,7 @@ impl Object { let raw = unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_Get_Index(c, self.1, context.as_raw(), index)) + |c| v8_sys::v8_Object_Get_Index(c, self.1, context.as_raw(), index)) .unwrap() }; Value(self.0.clone(), raw) @@ -1069,7 +1069,7 @@ impl Object { pub fn delete(&self, context: &context::Context, key: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_Delete_Key(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Object_Delete_Key(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1083,7 +1083,7 @@ impl Object { let m = util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_Delete_Index(c, self.1, context.as_raw(), index)) + |c| v8_sys::v8_Object_Delete_Index(c, self.1, context.as_raw(), index)) .unwrap(); assert!( m.is_set); @@ -1094,7 +1094,7 @@ impl Object { pub fn has(&self, context: &context::Context, key: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_Has_Key(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Object_Has_Key(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1107,7 +1107,7 @@ impl Object { unsafe { let m = util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_Has_Index(c, self.1, context.as_raw(), index)) + |c| v8_sys::v8_Object_Has_Index(c, self.1, context.as_raw(), index)) .unwrap(); assert!( m.is_set); @@ -1124,7 +1124,7 @@ impl Object { unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_GetPropertyNames(c, self.1, context.as_raw())) + |c| v8_sys::v8_Object_GetPropertyNames(c, self.1, context.as_raw())) .map(|p| Array(self.0.clone(), p)) .unwrap() } @@ -1136,7 +1136,7 @@ impl Object { unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_GetOwnPropertyNames(c, self.1, context.as_raw())) + |c| v8_sys::v8_Object_GetOwnPropertyNames(c, self.1, context.as_raw())) .map(|p| Array(self.0.clone(), p)) .unwrap() } @@ -1146,7 +1146,7 @@ impl Object { pub fn set_private(&self, context: &context::Context, key: &Private, value: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_SetPrivate(c, self.1, context.as_raw(), key.as_raw(), value.as_raw()) + v8_sys::v8_Object_SetPrivate(c, self.1, context.as_raw(), key.as_raw(), value.as_raw()) }) .unwrap(); @@ -1159,7 +1159,7 @@ impl Object { unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_GetPrivate(c, self.1, context.as_raw(), key.as_raw())) + |c| v8_sys::v8_Object_GetPrivate(c, self.1, context.as_raw(), key.as_raw())) .map(|p| Value(self.0.clone(), p)) .unwrap() } @@ -1168,7 +1168,7 @@ impl Object { pub fn delete_private(&self, context: &context::Context, key: &Private) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_DeletePrivate(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Object_DeletePrivate(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1180,7 +1180,7 @@ impl Object { pub fn has_private(&self, context: &context::Context, key: &Private) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_HasPrivate(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Object_HasPrivate(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1194,7 +1194,7 @@ impl Object { /// This does not skip objects marked to be skipped by `__proto__` and it does not consult the /// security handler. pub fn get_prototype(&self) -> Value { - let raw = unsafe { util::invoke(&self.0, |c| v8::v8_Object_GetPrototype(c, self.1)).unwrap() }; + let raw = unsafe { util::invoke(&self.0, |c| v8_sys::v8_Object_GetPrototype(c, self.1)).unwrap() }; Value(self.0.clone(), raw) } @@ -1205,7 +1205,7 @@ impl Object { pub fn set_prototype(&self, context: &context::Context, prototype: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_SetPrototype(c, self.1, context.as_raw(), prototype.as_raw()) + v8_sys::v8_Object_SetPrototype(c, self.1, context.as_raw(), prototype.as_raw()) }) .unwrap(); @@ -1222,7 +1222,7 @@ impl Object { let raw = unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Object_ObjectProtoToString(c, self.1, context.as_raw())) + |c| v8_sys::v8_Object_ObjectProtoToString(c, self.1, context.as_raw())) .unwrap() }; String(self.0.clone(), raw) @@ -1231,7 +1231,7 @@ impl Object { /// Returns the name of the function invoked as a constructor for this object. pub fn get_constructor_name(&self) -> String { let raw = - unsafe { util::invoke(&self.0, |c| v8::v8_Object_GetConstructorName(c, self.1)).unwrap() }; + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Object_GetConstructorName(c, self.1)).unwrap() }; String(self.0.clone(), raw) } @@ -1239,14 +1239,14 @@ impl Object { /// Gets the number of internal fields for this Object pub fn internal_field_count(&self) -> u32 { unsafe { - util::invoke(&self.0, |c| v8::v8_Object_InternalFieldCount(c, self.1)).unwrap() as u32 + util::invoke(&self.0, |c| v8_sys::v8_Object_InternalFieldCount(c, self.1)).unwrap() as u32 } } /// Gets the value from an internal field. pub unsafe fn get_internal_field(&self, index: u32) -> Value { let raw = util::invoke(&self.0, - |c| v8::v8_Object_GetInternalField(c, self.1, index as os::raw::c_int)) + |c| v8_sys::v8_Object_GetInternalField(c, self.1, index as os::raw::c_int)) .unwrap(); Value(self.0.clone(), raw) } @@ -1254,7 +1254,7 @@ impl Object { /// Sets the value in an internal field. pub unsafe fn set_internal_field(&self, index: u32, value: &Value) { util::invoke(&self.0, |c| { - v8::v8_Object_SetInternalField(c, self.1, index as os::raw::c_int, value.as_raw()) + v8_sys::v8_Object_SetInternalField(c, self.1, index as os::raw::c_int, value.as_raw()) }) .unwrap() } @@ -1265,7 +1265,7 @@ impl Object { /// leads to undefined behavior. pub unsafe fn get_aligned_pointer_from_internal_field(&self, index: u32) -> *mut A { util::invoke(&self.0, |c| { - v8::v8_Object_GetAlignedPointerFromInternalField(c, self.1, index as os::raw::c_int) + v8_sys::v8_Object_GetAlignedPointerFromInternalField(c, self.1, index as os::raw::c_int) }) .unwrap() as *mut A } @@ -1276,7 +1276,7 @@ impl Object { /// else leads to undefined behavior. pub unsafe fn set_aligned_pointer_in_internal_field(&self, index: u32, value: *mut A) { util::invoke(&self.0, |c| { - v8::v8_Object_SetAlignedPointerInInternalField(c, + v8_sys::v8_Object_SetAlignedPointerInInternalField(c, self.1, index as os::raw::c_int, value as *mut os::raw::c_void) @@ -1287,7 +1287,7 @@ impl Object { pub fn has_own_property(&self, context: &context::Context, key: &Name) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_HasOwnProperty_Key(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Object_HasOwnProperty_Key(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1299,7 +1299,7 @@ impl Object { pub fn has_own_property_index(&self, context: &context::Context, index: u32) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_HasOwnProperty_Index(c, self.1, context.as_raw(), index) + v8_sys::v8_Object_HasOwnProperty_Index(c, self.1, context.as_raw(), index) }) .unwrap(); @@ -1311,7 +1311,7 @@ impl Object { pub fn has_real_named_property(&self, context: &context::Context, key: &Name) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_HasRealNamedProperty(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Object_HasRealNamedProperty(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1323,7 +1323,7 @@ impl Object { pub fn has_real_indexed_property(&self, context: &context::Context, index: u32) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_HasRealIndexedProperty(c, self.1, context.as_raw(), index) + v8_sys::v8_Object_HasRealIndexedProperty(c, self.1, context.as_raw(), index) }) .unwrap(); @@ -1338,21 +1338,21 @@ impl Object { /// /// The return value will never be 0. Also, it is not guaranteed to be unique. pub fn get_identity_hash(&self) -> u32 { - unsafe { util::invoke(&self.0, |c| v8::v8_Object_GetIdentityHash(c, self.1)).unwrap() as u32 } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Object_GetIdentityHash(c, self.1)).unwrap() as u32 } } /// Clone this object with a fast but shallow copy. /// /// Values will point to the same values as the original object. pub fn clone_object(&self) -> Object { - let raw = unsafe { util::invoke(&self.0, |c| v8::v8_Object_Clone(c, self.1)).unwrap() }; + let raw = unsafe { util::invoke(&self.0, |c| v8_sys::v8_Object_Clone(c, self.1)).unwrap() }; Object(self.0.clone(), raw) } pub fn creation_context(&self) -> context::Context { unsafe { - let raw = util::invoke(&self.0, |c| v8::v8_Object_CreationContext(c, self.1)).unwrap(); + let raw = util::invoke(&self.0, |c| v8_sys::v8_Object_CreationContext(c, self.1)).unwrap(); context::Context::from_raw(&self.0, raw) } } @@ -1361,12 +1361,12 @@ impl Object { /// /// When an Object is callable this method returns true. pub fn is_callable(&self) -> bool { - unsafe { util::invoke(&self.0, |c| v8::v8_Object_IsCallable(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Object_IsCallable(c, self.1)).unwrap() } } /// True if this object is a constructor. pub fn is_constructor(&self) -> bool { - unsafe { util::invoke(&self.0, |c| v8::v8_Object_IsConstructor(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Object_IsConstructor(c, self.1)).unwrap() } } /// Call an Object as a function if a callback is set by the @@ -1375,7 +1375,7 @@ impl Object { let mut arg_ptrs = args.iter().map(|v| v.1).collect::>(); let raw = unsafe { try!(util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_CallAsFunction(c, + v8_sys::v8_Object_CallAsFunction(c, self.1, context.as_raw(), ptr::null_mut(), @@ -1396,7 +1396,7 @@ impl Object { let mut arg_ptrs = args.iter().map(|v| v.1).collect::>(); let raw = unsafe { try!(util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_CallAsFunction(c, + v8_sys::v8_Object_CallAsFunction(c, self.1, context.as_raw(), this.as_raw(), @@ -1418,7 +1418,7 @@ impl Object { let mut arg_ptrs = args.iter().map(|v| v.1).collect::>(); let raw = unsafe { try!(util::invoke_ctx(&self.0, context, |c| { - v8::v8_Object_CallAsConstructor(c, + v8_sys::v8_Object_CallAsConstructor(c, self.1, context.as_raw(), arg_ptrs.len() as i32, @@ -1429,12 +1429,12 @@ impl Object { } /// Creates an object from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::ObjectRef) -> Object { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::ObjectRef) -> Object { Object(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this object. - pub fn as_raw(&self) -> v8::ObjectRef { + pub fn as_raw(&self) -> v8_sys::ObjectRef { self.1 } } @@ -1445,42 +1445,42 @@ impl Array { let raw = unsafe { util::invoke_ctx(&isolate, context, - |c| v8::v8_Array_New(c, isolate.as_raw(), length as i32)) + |c| v8_sys::v8_Array_New(c, isolate.as_raw(), length as i32)) .unwrap() }; Array(isolate.clone(), raw) } /// Creates an array from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::ArrayRef) -> Array { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::ArrayRef) -> Array { Array(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this array. - pub fn as_raw(&self) -> v8::ArrayRef { + pub fn as_raw(&self) -> v8_sys::ArrayRef { self.1 } } impl Map { pub fn new(isolate: &isolate::Isolate) -> Map { - let raw = unsafe { util::invoke(&isolate, |c| v8::v8_Map_New(c, isolate.as_raw())).unwrap() }; + let raw = unsafe { util::invoke(&isolate, |c| v8_sys::v8_Map_New(c, isolate.as_raw())).unwrap() }; Map(isolate.clone(), raw) } pub fn size(&self) -> usize { - unsafe { util::invoke(&self.0, |c| v8::v8_Map_Size(c, self.1)).unwrap() as usize } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Map_Size(c, self.1)).unwrap() as usize } } pub fn clear(&self) { - unsafe { util::invoke(&self.0, |c| v8::v8_Map_Clear(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Map_Clear(c, self.1)).unwrap() } } pub fn get(&self, context: &context::Context, key: &Value) -> Value { let raw = unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Map_Get_Key(c, self.1, context.as_raw(), key.as_raw())) + |c| v8_sys::v8_Map_Get_Key(c, self.1, context.as_raw(), key.as_raw())) .unwrap() }; Value(self.0.clone(), raw) @@ -1489,7 +1489,7 @@ impl Map { pub fn set(&self, context: &context::Context, key: &Value, value: &Value) { unsafe { util::invoke_ctx(&self.0, context, |c| { - v8::v8_Map_Set_Key(c, self.1, context.as_raw(), key.as_raw(), value.as_raw()) + v8_sys::v8_Map_Set_Key(c, self.1, context.as_raw(), key.as_raw(), value.as_raw()) }) .unwrap(); } @@ -1499,7 +1499,7 @@ impl Map { unsafe { let m = util::invoke_ctx(&self.0, context, - |c| v8::v8_Map_Has_Key(c, self.1, context.as_raw(), key.as_raw())) + |c| v8_sys::v8_Map_Has_Key(c, self.1, context.as_raw(), key.as_raw())) .unwrap(); assert!( m.is_set); @@ -1510,7 +1510,7 @@ impl Map { pub fn delete(&self, context: &context::Context, key: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Map_Delete_Key(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Map_Delete_Key(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1522,17 +1522,17 @@ impl Map { /// Returns an array of length Size() * 2, where index N is the Nth key and index N + 1 is the /// Nth value. pub fn as_array(&self) -> Array { - let raw = unsafe { util::invoke(&self.0, |c| v8::v8_Map_AsArray(c, self.1)).unwrap() }; + let raw = unsafe { util::invoke(&self.0, |c| v8_sys::v8_Map_AsArray(c, self.1)).unwrap() }; Array(self.0.clone(), raw) } /// Creates a map from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::MapRef) -> Map { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::MapRef) -> Map { Map(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this map. - pub fn as_raw(&self) -> v8::MapRef { + pub fn as_raw(&self) -> v8_sys::MapRef { self.1 } } @@ -1540,23 +1540,23 @@ impl Map { impl Set { /// Creates a new empty Set. pub fn new(isolate: &isolate::Isolate) -> Set { - let raw = unsafe { util::invoke(&isolate, |c| v8::v8_Set_New(c, isolate.as_raw())).unwrap() }; + let raw = unsafe { util::invoke(&isolate, |c| v8_sys::v8_Set_New(c, isolate.as_raw())).unwrap() }; Set(isolate.clone(), raw) } pub fn size(&self) -> usize { - unsafe { util::invoke(&self.0, |c| v8::v8_Set_Size(c, self.1)).unwrap() as usize } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Set_Size(c, self.1)).unwrap() as usize } } pub fn clear(&self) { - unsafe { util::invoke(&self.0, |c| v8::v8_Set_Clear(c, self.1)).unwrap() } + unsafe { util::invoke(&self.0, |c| v8_sys::v8_Set_Clear(c, self.1)).unwrap() } } pub fn add(&self, context: &context::Context, key: &Value) { unsafe { util::invoke_ctx(&self.0, context, - |c| v8::v8_Set_Add(c, self.1, context.as_raw(), key.as_raw())) + |c| v8_sys::v8_Set_Add(c, self.1, context.as_raw(), key.as_raw())) .unwrap(); } } @@ -1565,7 +1565,7 @@ impl Set { unsafe { let m = util::invoke_ctx(&self.0, context, - |c| v8::v8_Set_Has_Key(c, self.1, context.as_raw(), key.as_raw())) + |c| v8_sys::v8_Set_Has_Key(c, self.1, context.as_raw(), key.as_raw())) .unwrap(); assert!( m.is_set); @@ -1576,7 +1576,7 @@ impl Set { pub fn delete(&self, context: &context::Context, key: &Value) -> bool { unsafe { let m = util::invoke_ctx(&self.0, context, |c| { - v8::v8_Set_Delete_Key(c, self.1, context.as_raw(), key.as_raw()) + v8_sys::v8_Set_Delete_Key(c, self.1, context.as_raw(), key.as_raw()) }) .unwrap(); @@ -1587,17 +1587,17 @@ impl Set { /// Returns an array of the keys in this Set. pub fn as_array(&self) -> Array { - let raw = unsafe { util::invoke(&self.0, |c| v8::v8_Set_AsArray(c, self.1)).unwrap() }; + let raw = unsafe { util::invoke(&self.0, |c| v8_sys::v8_Set_AsArray(c, self.1)).unwrap() }; Array(self.0.clone(), raw) } /// Creates a set from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::SetRef) -> Set { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::SetRef) -> Set { Set(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this set. - pub fn as_raw(&self) -> v8::SetRef { + pub fn as_raw(&self) -> v8_sys::SetRef { self.1 } } @@ -1621,12 +1621,12 @@ impl Function { closure.set_internal_field(0, &callback_ext); let raw = util::invoke_ctx(&isolate, context, |c| { - v8::v8_Function_New(c, + v8_sys::v8_Function_New(c, context.as_raw(), Some(util::callback), (&closure as &Value).as_raw(), length as os::raw::c_int, - v8::ConstructorBehavior::ConstructorBehavior_kAllow) + v8_sys::ConstructorBehavior::ConstructorBehavior_kAllow) }) .unwrap(); Function(isolate.clone(), raw) @@ -1639,7 +1639,7 @@ impl Function { let mut arg_ptrs = args.iter().map(|v| v.1).collect::>(); let raw = unsafe { try!(util::invoke_ctx(&self.0, context, |c| { - v8::v8_Function_Call(c, + v8_sys::v8_Function_Call(c, self.1, context.as_raw(), ptr::null_mut(), @@ -1660,7 +1660,7 @@ impl Function { let mut arg_ptrs = args.iter().map(|v| v.1).collect::>(); let raw = unsafe { try!(util::invoke_ctx(&self.0, context, |c| { - v8::v8_Function_Call(c, + v8_sys::v8_Function_Call(c, self.1, context.as_raw(), this.as_raw(), @@ -1672,12 +1672,12 @@ impl Function { } /// Creates a function from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::FunctionRef) -> Function { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::FunctionRef) -> Function { Function(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this function. - pub fn as_raw(&self) -> v8::FunctionRef { + pub fn as_raw(&self) -> v8_sys::FunctionRef { self.1 } } @@ -1685,23 +1685,23 @@ impl Function { impl External { pub unsafe fn new(isolate: &isolate::Isolate, value: *mut A) -> External { let raw = util::invoke(&isolate, |c| { - v8::v8_External_New(c, isolate.as_raw(), value as *mut os::raw::c_void) + v8_sys::v8_External_New(c, isolate.as_raw(), value as *mut os::raw::c_void) }) .unwrap(); External(isolate.clone(), raw) } pub unsafe fn value(&self) -> *mut A { - util::invoke(&self.0, |c| v8::v8_External_Value(c, self.1)).unwrap() as *mut A + util::invoke(&self.0, |c| v8_sys::v8_External_Value(c, self.1)).unwrap() as *mut A } /// Creates an external from a set of raw pointers. - pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8::ExternalRef) -> External { + pub unsafe fn from_raw(isolate: &isolate::Isolate, raw: v8_sys::ExternalRef) -> External { External(isolate.clone(), raw) } /// Returns the underlying raw pointer behind this external. - pub fn as_raw(&self) -> v8::ExternalRef { + pub fn as_raw(&self) -> v8_sys::ExternalRef { self.1 } } @@ -1709,7 +1709,7 @@ impl External { impl Exception { pub fn range_error(isolate: &isolate::Isolate, message: &String) -> Value { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Exception_RangeError(c, message.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Exception_RangeError(c, message.as_raw())).unwrap() }; Value(isolate.clone(), raw) } @@ -1717,7 +1717,7 @@ impl Exception { pub fn reference_error(isolate: &isolate::Isolate, message: &String) -> Value { let raw = unsafe { util::invoke(&isolate, - |c| v8::v8_Exception_ReferenceError(c, message.as_raw())) + |c| v8_sys::v8_Exception_ReferenceError(c, message.as_raw())) .unwrap() }; Value(isolate.clone(), raw) @@ -1725,21 +1725,21 @@ impl Exception { pub fn syntax_error(isolate: &isolate::Isolate, message: &String) -> Value { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Exception_SyntaxError(c, message.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Exception_SyntaxError(c, message.as_raw())).unwrap() }; Value(isolate.clone(), raw) } pub fn type_error(isolate: &isolate::Isolate, message: &String) -> Value { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Exception_TypeError(c, message.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Exception_TypeError(c, message.as_raw())).unwrap() }; Value(isolate.clone(), raw) } pub fn error(isolate: &isolate::Isolate, message: &String) -> Value { let raw = unsafe { - util::invoke(&isolate, |c| v8::v8_Exception_Error(c, message.as_raw())).unwrap() + util::invoke(&isolate, |c| v8_sys::v8_Exception_Error(c, message.as_raw())).unwrap() }; Value(isolate.clone(), raw) } @@ -1890,76 +1890,76 @@ inherit!(External, Value); // unsafe: Don't add another `drop!` line if you don't know the implications (see the comments // around the macro declaration). -reference!(Data, v8::v8_Data_CloneRef, v8::v8_Data_DestroyRef); -reference!(Value, v8::v8_Value_CloneRef, v8::v8_Value_DestroyRef); -reference!(Primitive, v8::v8_Primitive_CloneRef, v8::v8_Primitive_DestroyRef); -reference!(Boolean, v8::v8_Boolean_CloneRef, v8::v8_Boolean_DestroyRef); -reference!(Name, v8::v8_Name_CloneRef, v8::v8_Name_DestroyRef); -reference!(String, v8::v8_String_CloneRef, v8::v8_String_DestroyRef); -reference!(Symbol, v8::v8_Symbol_CloneRef, v8::v8_Symbol_DestroyRef); -reference!(Private, v8::v8_Private_CloneRef, v8::v8_Private_DestroyRef); -reference!(Number, v8::v8_Number_CloneRef, v8::v8_Number_DestroyRef); -reference!(Integer, v8::v8_Integer_CloneRef, v8::v8_Integer_DestroyRef); -reference!(Int32, v8::v8_Int32_CloneRef, v8::v8_Int32_DestroyRef); -reference!(Uint32, v8::v8_Uint32_CloneRef, v8::v8_Uint32_DestroyRef); -reference!(Object, v8::v8_Object_CloneRef, v8::v8_Object_DestroyRef); -reference!(Array, v8::v8_Array_CloneRef, v8::v8_Array_DestroyRef); -reference!(Map, v8::v8_Map_CloneRef, v8::v8_Map_DestroyRef); -reference!(Set, v8::v8_Set_CloneRef, v8::v8_Set_DestroyRef); -reference!(Function, v8::v8_Function_CloneRef, v8::v8_Function_DestroyRef); -reference!(Promise, v8::v8_Promise_CloneRef, v8::v8_Promise_DestroyRef); -reference!(Proxy, v8::v8_Proxy_CloneRef, v8::v8_Proxy_DestroyRef); +reference!(Data, v8_sys::v8_Data_CloneRef, v8_sys::v8_Data_DestroyRef); +reference!(Value, v8_sys::v8_Value_CloneRef, v8_sys::v8_Value_DestroyRef); +reference!(Primitive, v8_sys::v8_Primitive_CloneRef, v8_sys::v8_Primitive_DestroyRef); +reference!(Boolean, v8_sys::v8_Boolean_CloneRef, v8_sys::v8_Boolean_DestroyRef); +reference!(Name, v8_sys::v8_Name_CloneRef, v8_sys::v8_Name_DestroyRef); +reference!(String, v8_sys::v8_String_CloneRef, v8_sys::v8_String_DestroyRef); +reference!(Symbol, v8_sys::v8_Symbol_CloneRef, v8_sys::v8_Symbol_DestroyRef); +reference!(Private, v8_sys::v8_Private_CloneRef, v8_sys::v8_Private_DestroyRef); +reference!(Number, v8_sys::v8_Number_CloneRef, v8_sys::v8_Number_DestroyRef); +reference!(Integer, v8_sys::v8_Integer_CloneRef, v8_sys::v8_Integer_DestroyRef); +reference!(Int32, v8_sys::v8_Int32_CloneRef, v8_sys::v8_Int32_DestroyRef); +reference!(Uint32, v8_sys::v8_Uint32_CloneRef, v8_sys::v8_Uint32_DestroyRef); +reference!(Object, v8_sys::v8_Object_CloneRef, v8_sys::v8_Object_DestroyRef); +reference!(Array, v8_sys::v8_Array_CloneRef, v8_sys::v8_Array_DestroyRef); +reference!(Map, v8_sys::v8_Map_CloneRef, v8_sys::v8_Map_DestroyRef); +reference!(Set, v8_sys::v8_Set_CloneRef, v8_sys::v8_Set_DestroyRef); +reference!(Function, v8_sys::v8_Function_CloneRef, v8_sys::v8_Function_DestroyRef); +reference!(Promise, v8_sys::v8_Promise_CloneRef, v8_sys::v8_Promise_DestroyRef); +reference!(Proxy, v8_sys::v8_Proxy_CloneRef, v8_sys::v8_Proxy_DestroyRef); reference!(ArrayBuffer, - v8::v8_ArrayBuffer_CloneRef, - v8::v8_ArrayBuffer_DestroyRef); + v8_sys::v8_ArrayBuffer_CloneRef, + v8_sys::v8_ArrayBuffer_DestroyRef); reference!(ArrayBufferView, - v8::v8_ArrayBufferView_CloneRef, - v8::v8_ArrayBufferView_DestroyRef); + v8_sys::v8_ArrayBufferView_CloneRef, + v8_sys::v8_ArrayBufferView_DestroyRef); reference!(TypedArray, - v8::v8_TypedArray_CloneRef, - v8::v8_TypedArray_DestroyRef); + v8_sys::v8_TypedArray_CloneRef, + v8_sys::v8_TypedArray_DestroyRef); reference!(Uint8Array, - v8::v8_Uint8Array_CloneRef, - v8::v8_Uint8Array_DestroyRef); + v8_sys::v8_Uint8Array_CloneRef, + v8_sys::v8_Uint8Array_DestroyRef); reference!(Uint8ClampedArray, - v8::v8_Uint8ClampedArray_CloneRef, - v8::v8_Uint8ClampedArray_DestroyRef); -reference!(Int8Array, v8::v8_Int8Array_CloneRef, v8::v8_Int8Array_DestroyRef); + v8_sys::v8_Uint8ClampedArray_CloneRef, + v8_sys::v8_Uint8ClampedArray_DestroyRef); +reference!(Int8Array, v8_sys::v8_Int8Array_CloneRef, v8_sys::v8_Int8Array_DestroyRef); reference!(Uint16Array, - v8::v8_Uint16Array_CloneRef, - v8::v8_Uint16Array_DestroyRef); + v8_sys::v8_Uint16Array_CloneRef, + v8_sys::v8_Uint16Array_DestroyRef); reference!(Int16Array, - v8::v8_Int16Array_CloneRef, - v8::v8_Int16Array_DestroyRef); + v8_sys::v8_Int16Array_CloneRef, + v8_sys::v8_Int16Array_DestroyRef); reference!(Uint32Array, - v8::v8_Uint32Array_CloneRef, - v8::v8_Uint32Array_DestroyRef); + v8_sys::v8_Uint32Array_CloneRef, + v8_sys::v8_Uint32Array_DestroyRef); reference!(Int32Array, - v8::v8_Int32Array_CloneRef, - v8::v8_Int32Array_DestroyRef); + v8_sys::v8_Int32Array_CloneRef, + v8_sys::v8_Int32Array_DestroyRef); reference!(Float32Array, - v8::v8_Float32Array_CloneRef, - v8::v8_Float32Array_DestroyRef); + v8_sys::v8_Float32Array_CloneRef, + v8_sys::v8_Float32Array_DestroyRef); reference!(Float64Array, - v8::v8_Float64Array_CloneRef, - v8::v8_Float64Array_DestroyRef); -reference!(DataView, v8::v8_DataView_CloneRef, v8::v8_DataView_DestroyRef); + v8_sys::v8_Float64Array_CloneRef, + v8_sys::v8_Float64Array_DestroyRef); +reference!(DataView, v8_sys::v8_DataView_CloneRef, v8_sys::v8_DataView_DestroyRef); reference!(SharedArrayBuffer, - v8::v8_SharedArrayBuffer_CloneRef, - v8::v8_SharedArrayBuffer_DestroyRef); -reference!(Date, v8::v8_Date_CloneRef, v8::v8_Date_DestroyRef); + v8_sys::v8_SharedArrayBuffer_CloneRef, + v8_sys::v8_SharedArrayBuffer_DestroyRef); +reference!(Date, v8_sys::v8_Date_CloneRef, v8_sys::v8_Date_DestroyRef); reference!(NumberObject, - v8::v8_NumberObject_CloneRef, - v8::v8_NumberObject_DestroyRef); + v8_sys::v8_NumberObject_CloneRef, + v8_sys::v8_NumberObject_DestroyRef); reference!(BooleanObject, - v8::v8_BooleanObject_CloneRef, - v8::v8_BooleanObject_DestroyRef); + v8_sys::v8_BooleanObject_CloneRef, + v8_sys::v8_BooleanObject_DestroyRef); reference!(StringObject, - v8::v8_StringObject_CloneRef, - v8::v8_StringObject_DestroyRef); + v8_sys::v8_StringObject_CloneRef, + v8_sys::v8_StringObject_DestroyRef); reference!(SymbolObject, - v8::v8_SymbolObject_CloneRef, - v8::v8_SymbolObject_DestroyRef); -reference!(RegExp, v8::v8_RegExp_CloneRef, v8::v8_RegExp_DestroyRef); -reference!(External, v8::v8_External_CloneRef, v8::v8_External_DestroyRef); -reference!(Exception, v8::v8_Exception_CloneRef, v8::v8_Exception_DestroyRef); + v8_sys::v8_SymbolObject_CloneRef, + v8_sys::v8_SymbolObject_DestroyRef); +reference!(RegExp, v8_sys::v8_RegExp_CloneRef, v8_sys::v8_RegExp_DestroyRef); +reference!(External, v8_sys::v8_External_CloneRef, v8_sys::v8_External_DestroyRef); +reference!(Exception, v8_sys::v8_Exception_CloneRef, v8_sys::v8_Exception_DestroyRef); diff --git a/v8-api/Cargo.toml b/v8-api/Cargo.toml deleted file mode 100644 index c13bd742..00000000 --- a/v8-api/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -authors = ["David Flemström "] -description = "A parser for v8.h files to extract a description of the V8 API heuristically. Used in build scripts, for example in v8-sys." -homepage = "https://dflemstr.github.io/v8-rs" -keywords = ["v8", "javascript", "api"] -license = "Apache-2.0" -name = "v8-api" -repository = "https://github.com/dflemstr/v8-rs/tree/master/v8-api" -version = "0.7.3" - -[dependencies] -env_logger = "0.4.0" -log = "0.3.6" - -[dependencies.clang] -features = ["clang_3_5", "runtime"] -version = "0.15.0" diff --git a/v8-api/src/bin/v8-api-rs-parse.rs b/v8-api/src/bin/v8-api-rs-parse.rs deleted file mode 100644 index 3769f0a4..00000000 --- a/v8-api/src/bin/v8-api-rs-parse.rs +++ /dev/null @@ -1,19 +0,0 @@ -extern crate env_logger; -extern crate v8_api; - -use std::env; -use std::path; - -fn main() { - env_logger::init().unwrap(); - - let header_file_path = if let Some(path) = env::args_os().nth(1) { - path::PathBuf::from(path) - } else if let Some(path) = env::var_os("V8_SOURCE") { - path::PathBuf::from(path).join("include").join("v8.h") - } else { - path::Path::new("/usr/include/v8.h").to_path_buf() - }; - - print!("{}", v8_api::read(&header_file_path, &[] as &[&path::Path])); -} diff --git a/v8-api/src/lib.rs b/v8-api/src/lib.rs deleted file mode 100644 index 07f46673..00000000 --- a/v8-api/src/lib.rs +++ /dev/null @@ -1,609 +0,0 @@ -extern crate clang; -#[macro_use] -extern crate log; - -use std::env; -use std::fmt; -use std::path; - -/// A description of the V8 API. -#[derive(Debug)] -pub struct Api { - /// The classes that the API consists of. - pub classes: Vec, -} - -/// A C++ class, -#[derive(Debug)] -pub struct Class { - /// The simple name of the class (without the `v8::` prefix). - pub name: String, - /// The methods of this class, in declaration order. - pub methods: Vec, -} - -/// A C++ method -#[derive(Debug)] -pub struct Method { - /// Whether the method is static. - pub is_static: bool, - /// The name of the method. - pub name: String, - /// A mangled version of the method that makes it unique among all - /// of the methods of its class. - pub mangled_name: String, - /// The arguments that the method takes, in declaration order. - pub args: Vec, - /// The return type of the method. - pub ret_type: RetType, -} - -/// The return type of a method. -#[derive(Debug)] -pub enum RetType { - /// The type is directly returned. For primitives `T`, this means - /// just `T` (e.g. `int`). For references to `T`, this means - /// `Local` (e.g. `Local`). For pointers to `T`, this - /// means a non-null pointer `T *`. - Direct(Type), - /// The type might be absent. For primitives `T`, this means - /// `Maybe` (e.g. `Maybe`). For references to `T`, this - /// means `MaybeLocal`. For pointers to `T`, this means a - /// nullable pointer `T *`. - Maybe(Type), -} - -/// A method argument. -#[derive(Debug)] -pub struct Arg { - /// The argument name. - pub name: String, - /// The type of the argument. - pub arg_type: Type, -} - -/// The types used in V8. -#[derive(Debug, Eq, PartialEq)] -pub enum Type { - /// The `void` type. - Void, - /// The `bool` type. - Bool, - - /// The `unsigned char` type. - UChar, - /// The `const unsigned char` type. - ConstUChar, - /// The `char` type. - Char, - /// The `const char` type. - ConstChar, - /// The `unsigned int` type. - UInt, - /// The `int` type. - Int, - /// The `unsigned long` type. - ULong, - /// The `long` type. - Long, - - /// The `uint8_t` type. - U8, - /// The `int8_t` type. - I8, - /// The `uint16_t` type. - U16, - /// The `int16_t` type. - I16, - /// The `uint32_t` type. - U32, - /// The `int32_t` type. - I32, - /// The `uint64_t` type. - U64, - /// The `int64_t` type. - I64, - /// The `double` type. - F64, - - /// The `size_t` type. - USize, - - /// A class with the specified name, without the `v8::` prefix. - Class(String), - /// An enum with the specified name, without the `v8::` prefix. - Enum(String), - /// A callback function pointer name, without the `v8::` prefix. - Callback(String), - /// An argument to a callback - CallbackLValue(String), - - /// A reference to the specified type, meaning a `Local` or - /// `MaybeLocal`. - Ref(Box), - /// A pointer to the specified type, i.e. `T *`. - Ptr(Box), - /// An array of the specified type, i.e. `T[]`. - Arr(Box), -} - -/// A method mangle rule. -struct MethodMangle { - /// The exact name of the method to mangle. - name: &'static str, - /// A unique part of the method signature. - signature: &'static str, - /// The mangled name of the method. - mangle: &'static str, -} - -/// Classes that we should not return because they are special. -#[cfg_attr(rustfmt, rustfmt_skip)] -const SPECIAL_CLASSES: &'static [&'static str] = &[ - // v8.h - // Allocation stuff - "Isolate", // Because part of RustContext (so chicken and egg methods) - "HandleScope", // Because stack local - "EscapableHandleScope", // Because stack local - "SealHandleScope", // Because stack local - "TryCatch", // Because stack local - - // Annoying classes - "ScriptOrigin", // Because it's sent around by-value - "PersistentHandleVisitor", // Only used on Isolate? - "EmbedderHeapTracer", // Can't be heap allocated? - "ValueSerializer", // Weird API and only on modern V8's - "ValueDeserializer", // Weird API and only on modern V8's - "ExtensionConfiguration", // Weird API - "Module", // Too experimental - "SnapshotCreator", // Snapshots not supported - - // v8-platform.h - // These are all pre-requisites for creating an Isolate so - // hand-roll them - "Platform", - "Task", - "IdleTask", -]; - -/// Methods that we should not return because they are special. -#[cfg_attr(rustfmt, rustfmt_skip)] -const SPECIAL_METHODS: &'static [(&'static str, &'static str)] = &[ - ("Script", "Compile"), // Because ScriptOrigin param - ("Message", "GetScriptOrigin"), // Because ScriptOrigin - ("String", "WriteUtf8"), // Because annoying-to-map signature - ("Object", "SetAlignedPointerInInternalFields"), // Because annoying-to-map signature - ("Object", "CallAsFunction"), // Because annoying-to-map signature - ("Object", "CallAsConstructor"), // Because annoying-to-map signature - ("Object", "NewInstance"), // Because annoying-to-map signature - ("Object", "Call"), // Because annoying-to-map signature - ("Function", "New"), // Because annoying-to-map signature - ("Function", "GetScriptOrigin"), // Because ScriptOrigin - ("Function", "NewInstance"), // Because annoying-to-map signature - ("Function", "Call"), // Because annoying-to-map signature - ("Template", "SetNativeDataProperty"), // Because annoying-to-map signature - ("Template", "SetLazyDataProperty"), // Because annoying-to-map signature - ("FunctionTemplate", "New"), // Because annoying-to-map signature - ("FunctionTemplate", "NewWithCache"), // Because annoying-to-map signature - ("ObjectTemplate", "SetAccessor"), // Because annoying-to-map signature - ("ObjectTemplate", "SetNamedPropertyHandler"), // Because annoying-to-map signature - ("ObjectTemplate", "SetIndexedPropertyHandler"), // Because annoying-to-map signature - ("ObjectTemplate", "SetCallAsFunctionHandler"), // Because annoying-to-map signature - ("ObjectTemplate", "SetAccessCheckCallback"), // Because annoying-to-map signature - ("ObjectTemplate", "SetAccessCheckCallbackAndHandler"), // Because annoying-to-map signature - ("Value", "IsFloat32x4"), // Too experimental - ("WasmCompiledModule", "Serialize"), // Breaks on ARM/Mac - ("WasmCompiledModule", "Deserialize"), // Breaks on ARM/Mac - ("ConvertableToTraceFormat", "AppendAsTraceFormat"), // Breaks on ARM - ("V8", "CreateSnapshotDataBlob"), // Because annoying-to-map signature - ("V8", "WarmUpSnapshotDataBlob"), // Because annoying-to-map signature - ("V8", "Initialize"), // V8::Initialize takes no context - ("V8", "Dispose"), // V8::Dispose takes no context - ("V8", "InitializePlatform"), // V8::InitializePlatform takes no context - ("V8", "ShutdownPlatform"), // V8::ShutdownPlatform takes no context -]; - -/// Default mangle rules. -#[cfg_attr(rustfmt, rustfmt_skip)] -const METHOD_MANGLES: &'static [MethodMangle] = &[ - MethodMangle { name: "Set", signature: "index", mangle: "Set_Index"}, - MethodMangle { name: "Set", signature: "key", mangle: "Set_Key"}, - MethodMangle { name: "CreateDataProperty", signature: "index", mangle: "CreateDataProperty_Index"}, - MethodMangle { name: "CreateDataProperty", signature: "key", mangle: "CreateDataProperty_Key"}, - MethodMangle { name: "Get", signature: "index", mangle: "Get_Index"}, - MethodMangle { name: "Get", signature: "key", mangle: "Get_Key"}, - MethodMangle { name: "Has", signature: "index", mangle: "Has_Index"}, - MethodMangle { name: "Has", signature: "key", mangle: "Has_Key"}, - MethodMangle { name: "Delete", signature: "index", mangle: "Delete_Index"}, - MethodMangle { name: "Delete", signature: "key", mangle: "Delete_Key"}, - MethodMangle { name: "HasOwnProperty", signature: "index", mangle: "HasOwnProperty_Index"}, - MethodMangle { name: "HasOwnProperty", signature: "key", mangle: "HasOwnProperty_Key"}, - MethodMangle { name: "GetPropertyNames", signature: "mode", mangle: "GetPropertyNames_Filter"}, - MethodMangle { name: "GetOwnPropertyNames", signature: "filter", mangle: "GetOwnPropertyNames_Filter"}, - MethodMangle { name: "InitializeExternalStartupData", signature: "natives_blob", mangle: "InitializeExternalStartupData_Blobs"}, - MethodMangle { name: "InitializeExternalStartupData", signature: "directory_path", mangle: "InitializeExternalStartupData_Directory"}, - MethodMangle { name: "New", signature: "shared_array_buffer", mangle: "New_Shared"}, - MethodMangle { name: "New", signature: "array_buffer", mangle: "New_Owned"}, - MethodMangle { name: "New", signature: "mode", mangle: "New_Mode"}, - MethodMangle { name: "Set", signature: "char", mangle: "Set_Raw"}, - MethodMangle { name: "SetNativeDataProperty", signature: "v8::Name", mangle: "SetNativeDataProperty_Name"}, - MethodMangle { name: "SetAccessor", signature: "v8::Name", mangle: "SetAccessor_Name"}, - MethodMangle { name: "SetHandler", signature: "v8::Name", mangle: "SetHandler_Name"}, -]; - -/// Reads the V8 API from the given file path pointing to a `v8.h` -/// file (or a file that includes `v8.h`), using the specified extra -/// includes if necessary. -/// -/// # Panics -/// -/// Since this library is supposed to be used in a build script, -/// panics if anything goes wrong whatsoever. -pub fn read(file_path: P1, extra_includes: &[P2]) -> Api - where P1: AsRef, - P2: AsRef -{ - let clang = clang::Clang::new().unwrap(); - let index = clang::Index::new(&clang, false, true); - - let mut args = vec!["-x".to_owned(), - "c++".to_owned(), - "--std=c++11".to_owned(), - "-DV8_DEPRECATION_WARNINGS".to_owned(), - "-DV8_IMMINENT_DEPRECATION_WARNINGS".to_owned()]; - - if cfg!(all(windows, target_env = "msvc")) { - args.push("-fms-compatibility-version=19".to_owned()); - } - - if let Ok(target) = env::var("TARGET") { - args.push("-target".to_owned()); - args.push(target.to_owned()); - } - - for include in extra_includes { - println!("-I{:?}", include.as_ref()); - if let Some(include_str) = include.as_ref().to_str() { - args.push(format!("-I{}", include_str)); - } - } - - let translation_unit = index.parser(file_path.as_ref()) - .arguments(&args) - .parse() - .unwrap(); - - build_api(&translation_unit.get_entity()) -} - -fn build_api(entity: &clang::Entity) -> Api { - let namespaces = entity.get_children() - .into_iter() - .filter(|e| e.get_name().map(|n| n == "v8").unwrap_or(false)); - let classes = namespaces.flat_map(|n| build_classes(&n).into_iter()).collect(); - Api { classes: classes } -} - -fn build_classes(entity: &clang::Entity) -> Vec { - entity.get_children() - .into_iter() - // Is a class - .filter(|e| e.get_kind() == clang::EntityKind::ClassDecl) - // Is not just a declaration - .filter(|e| !e.get_children().is_empty()) - // Is not nameless or special - .filter(|e| { - e.get_name().map(|ref n| !SPECIAL_CLASSES.contains(&n.as_str())).unwrap_or(false) - }) - .map(|e| build_class(&e)) - .collect::>() -} - -fn build_class(entity: &clang::Entity) -> Class { - let name = entity.get_name().unwrap(); - Class { - methods: entity.get_children() - .into_iter() - // Is a method - .filter(|e| e.get_kind() == clang::EntityKind::Method) - // Is not deprecated - .filter(|e| e.get_availability() == clang::Availability::Available) - // Is public - .filter(|e| e.get_accessibility() == Some(clang::Accessibility::Public)) - // Is not an operator or special - .filter(|e| { - e.get_name() - .map(|ref n| { - !n.starts_with("operator") && - !SPECIAL_METHODS.iter() - .any(|m| m.0 == name && m.1 == n) - }) - .unwrap_or(false) - }) - .flat_map(|e| build_method(&e) - .map_err(|err| { - warn!("Could not translate method {}", e.get_display_name().unwrap_or_else(||"(unnamed)".to_owned())); - err - })) - .collect(), - name: name, - } -} - -fn build_method(entity: &clang::Entity) -> Result { - let display_name = try!(entity.get_display_name().ok_or(())); - let name = try!(entity.get_name().ok_or(())); - let args = try!(entity.get_arguments().ok_or(())); - let args: Vec = try!(args.iter().map(|e| build_arg(&e)).collect()); - - let method_type = try!(entity.get_type().ok_or(())); - let method_type_display_name = method_type.get_display_name(); - let ret_type = try!(method_type.get_result_type().ok_or(())); - let ret_type = try!(build_ret_type(&ret_type)); - - let mangled_name = METHOD_MANGLES.iter() - .find(|m| { - m.name == name && - (args.iter().any(|a| a.name == m.signature) || display_name.contains(m.signature) || - method_type_display_name.contains(m.signature)) - }) - .map(|m| m.mangle.to_owned()); - - Ok(Method { - is_static: entity.is_static_method(), - mangled_name: mangled_name.unwrap_or_else(|| name.clone()), - name: name, - args: args, - ret_type: ret_type, - }) -} - -fn build_arg(entity: &clang::Entity) -> Result { - Ok(Arg { - name: try!(entity.get_name().ok_or(())), - arg_type: try!(build_type(&entity.get_type().unwrap())), - }) -} - -fn build_ret_type(typ: &clang::Type) -> Result { - if typ.get_kind() == clang::TypeKind::Unexposed { - let name = typ.get_display_name(); - - if name.starts_with("MaybeLocal<") { - let ref_type = try!(build_type(&get_first_tpl_arg(typ))); - Ok(RetType::Maybe(Type::Ref(Box::new(ref_type)))) - } else if name.starts_with("Maybe<") { - let ref_type = try!(build_type(&get_first_tpl_arg(typ))); - Ok(RetType::Maybe(ref_type)) - } else { - Ok(RetType::Direct(try!(build_type(typ)))) - } - } else { - Ok(RetType::Direct(try!(build_type(typ)))) - } -} - -fn build_type(typ: &clang::Type) -> Result { - match typ.get_kind() { - clang::TypeKind::Void => Ok(Type::Void), - clang::TypeKind::Bool => Ok(Type::Bool), - clang::TypeKind::CharS => { - if typ.is_const_qualified() { - Ok(Type::ConstChar) - } else { - Ok(Type::Char) - } - }, - clang::TypeKind::CharU => { - if typ.is_const_qualified() { - Ok(Type::ConstUChar) - } else { - Ok(Type::UChar) - } - }, - clang::TypeKind::UInt => Ok(Type::UInt), - clang::TypeKind::Int => Ok(Type::Int), - clang::TypeKind::ULong => Ok(Type::ULong), - clang::TypeKind::Long => Ok(Type::Long), - clang::TypeKind::Double => Ok(Type::F64), - clang::TypeKind::LongLong => Ok(Type::I64), - clang::TypeKind::ULongLong => Ok(Type::U64), - clang::TypeKind::Pointer => { - let inner = try!(typ.get_pointee_type().ok_or(())); - let inner = try!(build_type(&inner)); - Ok(Type::Ptr(Box::new(inner))) - } - clang::TypeKind::IncompleteArray => { - let inner = try!(typ.get_element_type().ok_or(())); - let inner = try!(build_type(&inner)); - Ok(Type::Arr(Box::new(inner))) - } - clang::TypeKind::Record => { - // TODO: is this right? - let name = typ.get_display_name().replace("v8::", ""); - if name.contains("::") { - warn!("No support for nested type {:?}", name); - Err(()) - } else { - Ok(Type::Class(name)) - } - } - clang::TypeKind::Enum => { - // TODO: is this right? - let name = typ.get_display_name().replace("v8::", ""); - if name.contains("::") { - warn!("No support for nested type {:?}", name); - Err(()) - } else { - Ok(Type::Enum(name)) - } - } - clang::TypeKind::Typedef => { - // TODO: is this right? - match typ.get_display_name().as_str() { - "uint8_t" | "const uint8_t" => Ok(Type::U8), - "int8_t" | "const int8_t" => Ok(Type::I8), - "uint16_t" | "const uint16_t" => Ok(Type::U16), - "int16_t" | "const int16_t" => Ok(Type::I16), - "uint32_t" | "const uint32_t" => Ok(Type::U32), - "int32_t" | "const int32_t" => Ok(Type::I32), - "uint64_t" | "const uint64_t" => Ok(Type::U64), - "int64_t" | "const int64_t" => Ok(Type::I64), - "double" | "const double" => Ok(Type::F64), - "size_t" | "const size_t" => Ok(Type::USize), - s if s.ends_with("Callback") => Ok(Type::Callback(s.to_owned())), - s => { - warn!("Unmapped type {:?} (a typedef)", s); - Err(()) - } - } - } - clang::TypeKind::Unexposed | clang::TypeKind::Elaborated => { - if typ.get_display_name().starts_with("Local<") { - let ref_type = try!(build_type(&get_first_tpl_arg(typ))); - Ok(Type::Ref(Box::new(ref_type))) - } else { - match typ.get_display_name().as_str() { - // For some reason these fail to map - "v8::Isolate" => Ok(Type::Class("Isolate".to_owned())), - "v8::ObjectTemplate" => Ok(Type::Class("ObjectTemplate".to_owned())), - "v8::Value" => Ok(Type::Class("Value".to_owned())), - "v8::Local" => { - Ok(Type::Ref(Box::new(Type::Class("String".to_owned())))) - } - "v8::Local" => { - Ok(Type::Ref(Box::new(Type::Class("FunctionTemplate".to_owned())))) - } - n => { - warn!("Unmapped type {:?} of kind {:?} (in unexposed exception table)", - n, - typ.get_kind()); - Err(()) - } - } - } - } - clang::TypeKind::LValueReference => { - match typ.get_display_name().as_str() { - "const v8::NamedPropertyHandlerConfiguration &" => { - Ok(Type::CallbackLValue("NamedPropertyHandlerConfiguration".to_owned())) - } - "const v8::IndexedPropertyHandlerConfiguration &" => { - Ok(Type::CallbackLValue("IndexedPropertyHandlerConfiguration".to_owned())) - } - n => { - warn!("Unmapped type {:?} of kind {:?} (in lvalue reference exception table)", - n, - typ.get_kind()); - Err(()) - } - } - } - _ => { - warn!("Unmapped type {:?} of kind {:?} (in kind dispatch table)", - typ.get_display_name(), - typ.get_kind()); - Err(()) - } - } -} - -fn get_first_tpl_arg<'a>(typ: &clang::Type<'a>) -> clang::Type<'a> { - let tpl_args = typ.get_template_argument_types().unwrap(); - tpl_args[0].unwrap() -} - -impl fmt::Display for Api { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for class in self.classes.iter() { - try!(writeln!(f, "{}", class)); - } - Ok(()) - } -} - -impl fmt::Display for Class { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(writeln!(f, "class {}", self.name)); - for method in self.methods.iter() { - try!(writeln!(f, " {}", method)); - } - Ok(()) - } -} - -impl fmt::Display for Method { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.is_static { - try!(write!(f, "static ")); - } - try!(write!(f, "{}(", self.name)); - - let mut needs_sep = false; - for arg in self.args.iter() { - if needs_sep { - try!(write!(f, ", ")); - } - needs_sep = true; - try!(write!(f, "{}", arg)); - } - try!(write!(f, ") -> {}", self.ret_type)); - - if self.mangled_name != self.name { - try!(write!(f, " {{{}}}", self.mangled_name)); - } - - Ok(()) - } -} - -impl fmt::Display for Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{type} {name}", name=self.name, type=self.arg_type) - } -} - -impl fmt::Display for RetType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - RetType::Direct(ref t) => write!(f, "{}", t), - RetType::Maybe(ref t) => write!(f, "maybe {}", t), - } - } -} - -impl fmt::Display for Type { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Type::Void => write!(f, "()"), - Type::Bool => write!(f, "bool"), - - Type::UChar => write!(f, "::std::os::raw::c_uchar"), - Type::ConstUChar => write!(f, "::std::os::raw::c_uchar"), - Type::Char => write!(f, "::std::os::raw::c_char"), - Type::ConstChar => write!(f, "::std::os::raw::c_char"), - Type::UInt => write!(f, "::std::os::raw::c_uint"), - Type::Int => write!(f, "::std::os::raw::c_int"), - Type::ULong => write!(f, "::std::os::raw::c_ulong"), - Type::Long => write!(f, "::std::os::raw::c_long"), - - Type::U8 => write!(f, "u8"), - Type::I8 => write!(f, "i8"), - Type::U16 => write!(f, "u16"), - Type::I16 => write!(f, "i16"), - Type::U32 => write!(f, "u32"), - Type::I32 => write!(f, "i32"), - Type::U64 => write!(f, "u64"), - Type::I64 => write!(f, "i64"), - Type::F64 => write!(f, "f64"), - Type::USize => write!(f, "usize"), - Type::Enum(ref e) => write!(f, "enum {}", e), - Type::Class(ref class) => write!(f, "class {}", class), - Type::Callback(ref callback) => write!(f, "callback {}", callback), - Type::CallbackLValue(ref v) => write!(f, "callback lvalue {}", v), - Type::Ptr(ref target) => write!(f, "*mut {}", target), - Type::Ref(ref target) => write!(f, "&{}", target), - Type::Arr(ref target) => write!(f, "[{}]", target), - } - } -} diff --git a/v8-sys/Cargo.toml b/v8-sys/Cargo.toml index 8f2f135a..dc6ef904 100644 --- a/v8-sys/Cargo.toml +++ b/v8-sys/Cargo.toml @@ -12,24 +12,7 @@ repository = "https://github.com/dflemstr/v8-rs/tree/master/v8-sys" version = "0.14.7" [build-dependencies] -bindgen = "0.22.0" -gcc = "0.3.38" -pkg-config = "0.3.8" - -[build-dependencies.clang] -features = ["runtime"] -version = "0.15.0" - -[build-dependencies.clang-sys] -features = ["runtime"] -version = "0.14.0" - -[build-dependencies.v8-api] -path = "../v8-api" -version = "0.7.0" - -[dev-dependencies] -lazy_static = "0.2.1" - -[features] -shared = [] +bindgen = "0.32.1" +cc = "1.0.4" +env_logger = "0.4.3" +pkg-config = "0.3.9" diff --git a/v8-sys/build.rs b/v8-sys/build.rs index 26960f0f..bcbe7e57 100644 --- a/v8-sys/build.rs +++ b/v8-sys/build.rs @@ -1,490 +1,60 @@ -extern crate v8_api; extern crate bindgen; -extern crate clang; -extern crate clang_sys; -extern crate gcc; +extern crate cc; +extern crate env_logger; extern crate pkg_config; use std::env; -use std::fmt; -use std::fs; -use std::io; use std::path; -const LIBS: [&'static str; 4] = ["v8_base", "v8_libbase", "v8_libsampler", "v8_nosnapshot"]; - -trait DisplayAsC { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result; -} - -struct C<'a, A>(&'a A) where A: 'a; - -impl<'a, A> fmt::Display for C<'a, A> - where A: DisplayAsC + 'a -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - DisplayAsC::fmt(self.0, f) - } -} - fn main() { - let out_dir_str = env::var_os("OUT_DIR").unwrap(); - let out_dir_path = path::Path::new(&out_dir_str); - - println!("cargo:rerun-if-changed=src/v8-trampoline.h"); - println!("cargo:rerun-if-changed=src/v8-glue.h"); - println!("cargo:rerun-if-changed=src/v8-glue.cc"); - - let api = read_api(); - - link_v8(); - - let decl_header_path = out_dir_path.join("v8-glue-decl-generated.h"); - write_decl_header(&api, &mut fs::File::create(&decl_header_path).unwrap()).unwrap(); - - let header_path = out_dir_path.join("v8-glue-generated.h"); - write_header(&api, &mut fs::File::create(&header_path).unwrap()).unwrap(); - - let cc_file_path = out_dir_path.join("v8-glue-generated.cc"); - write_cc_file(&api, &mut fs::File::create(&cc_file_path).unwrap()).unwrap(); - - build_glue(out_dir_path); - - let ffi_path = out_dir_path.join("ffi.rs"); - gen_bindings(out_dir_path, &ffi_path); -} - -fn read_api() -> v8_api::Api { - let mut extra_includes = vec![]; - - if path::Path::new("v8-build").exists() { - extra_includes.push(path::Path::new("v8-build/include").to_path_buf()); - } else if let Some(dir_str) = env::var_os("V8_SOURCE") { - extra_includes.push(path::PathBuf::from(dir_str).join("include")); - } - - let clang = clang_sys::support::Clang::find(None).expect("No clang found, is it installed?"); - extra_includes.extend_from_slice(&clang.c_search_paths); - - let trampoline_path = path::Path::new("src/v8-trampoline.h"); - - v8_api::read(trampoline_path, &extra_includes) -} - -fn link_v8() { - if path::Path::new("v8-build").exists() { - // rq build hack - println!("cargo:rustc-link-search=native=v8-build"); - println!("cargo:rustc-link-lib=static=v8-uber"); - } else if let Ok(libs_str) = env::var("V8_LIBS") { - println!("V8_LIBS={:?}", libs_str); - for lib_str in libs_str.split(char::is_whitespace) { - let path = path::Path::new(lib_str); - if let Some(dir) = path.parent() { - if dir.file_name().is_some() { - println!("cargo:rustc-link-search=native={}", dir.to_str().unwrap()); - } - } - let lib_name = path.file_name().unwrap().to_str().unwrap(); - if lib_name.starts_with("lib") && lib_name.ends_with(".a") { - println!("cargo:rustc-link-lib=static={}", - &lib_name[3..lib_name.len() - 2]); - } - } - } else if let Some(dir_str) = env::var_os("V8_BUILD") { - println!("using V8_BUILD={:?}", dir_str); - let dir = path::Path::new(&dir_str); - - maybe_search(dir); - - // make+gyp-based build tree - maybe_search(dir.join("lib")); - maybe_search(dir.join("obj.target/src")); - maybe_search(dir.join("obj.target/third_party/icu")); - - // ninja+gyp-based build tree - maybe_search(dir.join("lib")); - maybe_search(dir.join("obj/src")); - maybe_search(dir.join("obj/third_party/icu")); - - // TODO: for GN-based builds it doesn't seem like the build - // produces static archives; maybe run ar here? - - blind_link_libraries(); - } else { - let statik = !cfg!(feature = "shared"); - println!("preferring static linking: {}", statik); - let result = pkg_config::Config::new() - .statik(statik) - .probe("v8"); - if result.is_ok() { - println!("using pkg-config for library v8"); - } else { - println!("cargo:warning=pkg-config failed, falling back to naïve lib search: {:?}", - result); - - maybe_search("/usr/lib"); - maybe_search("/usr/local/lib"); - // TODO: hack: lazy way to fix the Travis build - maybe_search("/usr/lib/x86_64-linux-gnu"); - maybe_search("/usr/local/lib/x86_64-linux-gnu"); - maybe_search("/usr/lib/v8"); - maybe_search("/usr/local/lib/v8"); - maybe_search("/usr/local/opt/icu4c/lib"); // homebrew - - blind_link_libraries(); - } - } -} - -fn blind_link_libraries() { - if cfg!(feature = "shared") { - if cfg!(all(windows, target_env = "msvc")) { - println!("cargo:rustc-link-lib=dylib=v8.dll"); - println!("cargo:rustc-link-lib=static=v8_base"); - } else { - println!("cargo:rustc-link-lib=dylib=v8"); - println!("cargo:rustc-link-lib=dylib=icui18n"); - println!("cargo:rustc-link-lib=dylib=icuuc"); - } - } else { - for lib in LIBS.iter() { - println!("cargo:rustc-link-lib=static={}", lib); - } - println!("cargo:rustc-link-lib=static=icui18n"); - println!("cargo:rustc-link-lib=static=icuuc"); - if fs::metadata("/usr/lib/x86_64-linux-gnu/libicudata.a") - .map(|m| m.is_file()) - .unwrap_or(false) { - println!("cargo:rustc-link-lib=static=icudata"); - } - if fs::metadata("/usr/local/opt/icu4c/lib/libicudata.a") - .map(|m| m.is_file()) - .unwrap_or(false) { - println!("cargo:rustc-link-lib=static=icudata"); - } - } -} - -fn maybe_search

(dir: P) - where P: AsRef -{ - let dir = dir.as_ref(); - if fs::metadata(dir).map(|m| m.is_dir()).unwrap_or(false) { - println!("cargo:rustc-link-search=native={}", dir.to_string_lossy()); - } -} - -fn gen_bindings(out_dir_path: &path::Path, bindings_path: &path::Path) { - use std::io::Write; - let mut bindings = bindgen::builder() - .header("src/v8-glue.h") - .emit_builtins() - .no_unstable_rust() - //bindings.remove_prefix("v8_"); - .clang_arg("-Isrc") - .clang_arg(format!("-I{}", out_dir_path.to_string_lossy())); - - if let Some(dir_str) = env::var_os("V8_SOURCE") { - println!("V8_SOURCE={:?}", dir_str); - let dir = path::Path::new(&dir_str); - bindings = bindings.clang_arg(format!("-I{}", dir.join("include").to_string_lossy())); - } else { - println!("V8_SOURCE not set, searching system paths"); - } - - let generated_bindings = bindings.generate().unwrap(); - - let mut bindings_file = fs::File::create(bindings_path).unwrap(); - writeln!(bindings_file, "mod ffi {{").unwrap(); - generated_bindings.write(Box::new(&mut bindings_file)).unwrap(); - writeln!(bindings_file, "}}").unwrap(); -} - -fn build_glue(out_dir_path: &path::Path) { - let mut config = gcc::Config::new(); - - if let Some(dir_str) = env::var_os("V8_SOURCE") { - let dir = path::Path::new(&dir_str); - config.include(dir.join("include")); - } - - if path::Path::new("v8-build").exists() { - config.include("v8-build/include"); - } - - config.include("src"); - config.include(out_dir_path); - config.cpp(true); - - if let Ok(target) = env::var("TARGET") { - if target.contains("musl") { - // This is a bit of a hack... we know this string is inserted as a - // "cargo:rustc-link-lib={}" format argument, so we can force it to be linked statically - // like this. - config.cpp_link_stdlib(Some("static=stdc++")); - } - } - - config.flag("-std=c++11"); - config.flag("-Wall"); - config.file("src/v8-glue.cc"); - config.compile("libv8sysglue.a"); -} - -fn write_decl_header(api: &v8_api::Api, mut out: W) -> io::Result<()> - where W: io::Write -{ - try!(writeln!(out, "#pragma once")); - - for class in api.classes.iter() { - try!(writeln!(out, "")); - try!(writeln!(out, "#if defined __cplusplus")); - try!(writeln!(out, "typedef v8::{class} *{class}Ptr;", class = class.name)); - try!(writeln!(out, - "typedef v8::Persistent *{class}Ref;", - class = class.name)); - try!(writeln!(out, "#else")); - try!(writeln!(out, - "typedef struct _{class} *{class}Ptr;", - class = class.name)); - try!(writeln!(out, - "typedef struct _{class}Ref *{class}Ref;", - class = class.name)); - try!(writeln!(out, "#endif /* defined __cplusplus */")); - } - - Ok(()) -} - -fn write_header(api: &v8_api::Api, mut out: W) -> io::Result<()> - where W: io::Write -{ - try!(writeln!(out, "#pragma once")); - - for class in api.classes.iter() { - try!(writeln!(out, "")); - - for method in class.methods.iter() { - try!(write!(out, - "{retty} v8_{class}_{method}(RustContext c", - retty = C(&method.ret_type), - class = class.name, - method = method.mangled_name)); - - if !method.is_static { - try!(write!(out, ", {class}Ref self", class = class.name)); - } - - for arg in method.args.iter() { - try!(write!(out, ", {arg}", arg = C(arg))); - } - try!(writeln!(out, ");")); - } - - try!(writeln!(out, - "{class}Ref v8_{class}_CloneRef(RustContext c, {class}Ref self);", - class = class.name)); - - try!(writeln!(out, - "void v8_{class}_DestroyRef({class}Ref self);", - class = class.name)); - - try!(writeln!(out, - "void v8_{class}_DestroyPtr({class}Ptr self);", - class = class.name)); - } - - Ok(()) -} - -fn write_cc_file(api: &v8_api::Api, mut out: W) -> io::Result<()> - where W: io::Write -{ - for class in api.classes.iter() { - for method in class.methods.iter() { - try!(writeln!(out, "")); - try!(write!(out, - "{retty} v8_{class}_{method}(RustContext c", - retty = C(&method.ret_type), - class = class.name, - method = method.mangled_name)); - - if !method.is_static { - try!(write!(out, ", {class}Ref self", class = class.name)); - } - - for arg in method.args.iter() { - try!(write!(out, ", {arg}", arg = C(arg))); - } - try!(writeln!(out, ") {{")); - - try!(writeln!(out, " v8::Isolate::Scope __isolate_scope(c.isolate);")); - try!(writeln!(out, " v8::HandleScope __handle_scope(c.isolate);")); - try!(writeln!(out, " v8::TryCatch __try_catch(c.isolate);")); - - let context_type = v8_api::Type::Ref(Box::new(v8_api::Type::Class("Context" - .to_owned()))); - if let Some(arg) = method.args.iter().find(|ref a| a.arg_type == context_type) { - // There should only be one context but who knows - try!(writeln!(out, - " auto wrapped_{ctx} = wrap(c.isolate, {ctx});", - ctx = arg.name)); - try!(writeln!(out, - " v8::Context::Scope {ctx}_scope(wrapped_{ctx});", - ctx = arg.name)); - } - - for arg in method.args.iter() { - try!(writeln!(out, - " auto {arg}_wrapped = wrap(c.isolate, {arg});", - arg = arg.name)); - } - - if let v8_api::RetType::Direct(v8_api::Type::Void) = method.ret_type { - try!(write!(out, " ")); - } else { - try!(write!(out, " auto result = ")); - } - if method.is_static { - try!(write!(out, - "v8::{class}::{method}(", - class = class.name, - method = method.name)); - } else { - try!(write!(out, "self->Get(c.isolate)->{method}(", method = method.name)); - } - - let mut needs_sep = false; - for arg in method.args.iter() { - if needs_sep { - try!(write!(out, ", ")); - } - needs_sep = true; - try!(write!(out, "{arg}_wrapped", arg = arg.name)); - } - try!(writeln!(out, ");")); - if let v8_api::RetType::Direct(v8_api::Type::Void) = method.ret_type { - try!(writeln!(out, " handle_exception(c, __try_catch);")); - } else { - try!(writeln!(out, " handle_exception(c, __try_catch);")); - try!(writeln!(out, - " return {unwrapper}(c.isolate, result);", - unwrapper = unwrapper(&method.ret_type))); - } - try!(writeln!(out, "}}")); - } - - try!(writeln!(out, "")); - try!(writeln!(out, - "{class}Ref v8_{class}_CloneRef(RustContext c, {class}Ref self) {{", - class = class.name)); - try!(writeln!(out, " v8::HandleScope __handle_scope(c.isolate);")); - try!(writeln!(out, " return unwrap(c.isolate, wrap(c.isolate, self));")); - try!(writeln!(out, "}}")); - try!(writeln!(out, "")); - try!(writeln!(out, - "void v8_{class}_DestroyRef({class}Ref self) {{", - class = class.name)); - try!(writeln!(out, " self->Reset();")); - try!(writeln!(out, " delete self;")); - try!(writeln!(out, "}}")); - try!(writeln!(out, "")); - try!(writeln!(out, - "void v8_{class}_DestroyPtr({class}Ptr self) {{", - class = class.name)); - try!(writeln!(out, " delete self;")); - try!(writeln!(out, "}}")); - } - - Ok(()) -} - -fn unwrapper(ret_type: &v8_api::RetType) -> &str { - use v8_api::*; - match *ret_type { - RetType::Maybe(Type::Bool) => "unwrap_maybe_bool", - RetType::Maybe(Type::Int) => "unwrap_maybe_int", - RetType::Maybe(Type::UInt) => "unwrap_maybe_uint", - RetType::Maybe(Type::Long) => "unwrap_maybe_long", - RetType::Maybe(Type::ULong) => "unwrap_maybe_ulong", - RetType::Maybe(Type::U32) => "unwrap_maybe_u32", - RetType::Maybe(Type::I32) => "unwrap_maybe_i32", - RetType::Maybe(Type::U64) => "unwrap_maybe_u64", - RetType::Maybe(Type::I64) => "unwrap_maybe_i64", - RetType::Maybe(Type::F64) => "unwrap_maybe_f64", - _ => "unwrap", - } -} - -impl DisplayAsC for v8_api::Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {}", C(&self.arg_type), self.name) - } -} - -impl DisplayAsC for v8_api::RetType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use v8_api::*; - match *self { - RetType::Direct(ref t) => DisplayAsC::fmt(t, f), - RetType::Maybe(Type::Bool) => write!(f, "MaybeBool"), - RetType::Maybe(Type::Int) => write!(f, "MaybeInt"), - RetType::Maybe(Type::UInt) => write!(f, "MaybeUInt"), - RetType::Maybe(Type::Long) => write!(f, "MaybeLong"), - RetType::Maybe(Type::ULong) => write!(f, "MaybeULong"), - RetType::Maybe(Type::U32) => write!(f, "MaybeU32"), - RetType::Maybe(Type::I32) => write!(f, "MaybeI32"), - RetType::Maybe(Type::F64) => write!(f, "MaybeF64"), - RetType::Maybe(Type::U64) => write!(f, "MaybeU64"), - RetType::Maybe(Type::I64) => write!(f, "MaybeI64"), - // TODO: potentially maybeify more types here - RetType::Maybe(ref t) => DisplayAsC::fmt(t, f), - } - } -} - -impl DisplayAsC for v8_api::Type { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use v8_api::*; - match *self { - Type::Void => write!(f, "void"), - Type::Bool => write!(f, "bool"), - Type::UChar => write!(f, "char"), - Type::ConstUChar => write!(f, "const char"), - Type::Char => write!(f, "char"), - Type::ConstChar => write!(f, "const char"), - Type::UInt => write!(f, "unsigned int"), - Type::Int => write!(f, "int"), - Type::ULong => write!(f, "unsigned long"), - Type::Long => write!(f, "long"), - Type::U8 => write!(f, "uint8_t"), - Type::I8 => write!(f, "int8_t"), - Type::U16 => write!(f, "uint16_t"), - Type::I16 => write!(f, "int16_t"), - Type::U32 => write!(f, "uint32_t"), - Type::I32 => write!(f, "int32_t"), - Type::U64 => write!(f, "uint64_t"), - Type::I64 => write!(f, "int64_t"), - Type::F64 => write!(f, "double"), - Type::USize => write!(f, "size_t"), - Type::Class(ref name) => write!(f, "{}", name), - Type::Enum(ref name) => write!(f, "{}", name), - Type::Callback(ref name) => write!(f, "{}", name), - Type::CallbackLValue(ref name) => write!(f, "{}", name), - Type::Ref(ref target) => { - match **target { - Type::Class(ref name) => write!(f, "{}Ref", name), - ref t => write!(f, "&{}", C(t)), - } - } - Type::Ptr(ref target) => { - match **target { - Type::Class(ref name) => write!(f, "{}Ptr", name), - ref t => write!(f, "{} *", C(t)), - } - } - Type::Arr(ref target) => write!(f, "{}[]", C(&**target)), - } - } + env_logger::init().unwrap(); + + pkg_config::Config::new() + .atleast_version("6.0.0.0") + .probe("v8") + .expect("unable to locate V8 via pkg-config"); + + cc::Build::new() + .cpp(true) + .warnings(true) + .flag("--std=c++11") + // So that we can use all functions via FFI + .flag("-fkeep-inline-functions") + .file("src/allocator.cpp") + .file("src/isolate.cpp") + .file("src/platform.cpp") + .compile("librust-v8-impls.a"); + + let bindings = bindgen::Builder::default() + .header("src/wrapper.hpp") + .rust_target(bindgen::RustTarget::Nightly) + .clang_arg("--std=c++11") + .whitelist_type("v8::.*") + .whitelist_type("rust_v8_impls::.*") + .whitelist_function("v8::.*") + .whitelist_function("rust_v8_impls::.*") + .whitelist_var("v8::.*") + .whitelist_var("rust_v8_impls::.*") + // Because there are some layout problems with these + .opaque_type("std::.*") + // For some reason bindgen output is corrupt (syntax errors) for these types + .blacklist_type("v8::JitCodeEvent__bindgen.*") + .blacklist_type(".*DisallowJavascriptExecutionScope.*") + .blacklist_type(".*SuppressMicrotaskExecutionScope.*") + // We want to re-structure the modules a bit and hide the "root" module + .raw_line("#[doc(hidden)]") + .generate_inline_functions(true) + .enable_cxx_namespaces() + .derive_debug(true) + .derive_hash(true) + .derive_eq(true) + .derive_partialeq(true) + .generate() + .expect("unable to generate v8 bindings"); + + let out_path = path::PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR env var not set")); + + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("unable to write bindings file"); } diff --git a/v8-sys/src/allocator.cpp b/v8-sys/src/allocator.cpp new file mode 100644 index 00000000..7cb239f3 --- /dev/null +++ b/v8-sys/src/allocator.cpp @@ -0,0 +1,131 @@ +#include "wrapper.hpp" + +namespace rust_v8_impls { + +class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { +public: + ArrayBufferAllocator(ArrayBufferAllocatorFunctions functions, void *self, + v8::ArrayBuffer::Allocator *fallback) + : _functions(functions), _self(self), _fallback(fallback) {} + + virtual ~ArrayBufferAllocator() { + if (this->_functions.Destroy) { + auto super = [this]() { delete this->_fallback; }; + auto thunk = [](void *arg) { (*static_cast(arg))(); }; + this->_functions.Destroy(this->_self, thunk, &super); + } else { + delete this->_fallback; + } + } + + virtual void *Allocate(size_t length) { + if (this->_functions.Allocate) { + auto super = [this](size_t length) { + return this->_fallback->Allocate(length); + }; + auto thunk = [](void *arg, size_t length) { + return (*static_cast(arg))(length); + }; + return this->_functions.Allocate(this->_self, thunk, &super, length); + } else { + return this->_fallback->Allocate(length); + } + } + + virtual void *AllocateUninitialized(size_t length) { + if (this->_functions.AllocateUninitialized) { + auto super = [this](size_t length) { + return this->_fallback->AllocateUninitialized(length); + }; + auto thunk = [](void *arg, size_t length) { + return (*static_cast(arg))(length); + }; + return this->_functions.AllocateUninitialized(this->_self, thunk, &super, + length); + } else { + return this->_fallback->AllocateUninitialized(length); + } + } + + virtual void *Reserve(size_t length) { + if (this->_functions.Reserve) { + auto super = [this](size_t length) { + return this->_fallback->Reserve(length); + }; + auto thunk = [](void *arg, size_t length) { + return (*static_cast(arg))(length); + }; + return this->_functions.Reserve(this->_self, thunk, &super, length); + } else { + return this->_fallback->Reserve(length); + } + } + + virtual void Free(void *data, size_t length) { + if (this->_functions.Free) { + auto super = [this](void *data, size_t length) { + return this->_fallback->Free(data, length); + }; + auto thunk = [](void *arg, void *data, size_t length) { + (*static_cast(arg))(data, length); + }; + this->_functions.Free(this->_self, thunk, &super, data, length); + } else { + this->_fallback->Free(data, length); + } + } + + virtual void Free(void *data, size_t length, + v8::ArrayBuffer::Allocator::AllocationMode mode) { + if (this->_functions.FreeMode) { + auto super = [this](void *data, size_t length, + v8::ArrayBuffer::Allocator::AllocationMode mode) { + return this->_fallback->Free(data, length, mode); + }; + auto thunk = [](void *arg, void *data, size_t length, + v8::ArrayBuffer::Allocator::AllocationMode mode) { + (*static_cast(arg))(data, length, mode); + }; + this->_functions.FreeMode(this->_self, thunk, &super, data, length, mode); + } else { + this->_fallback->Free(data, length, mode); + } + } + + virtual void + SetProtection(void *data, size_t length, + v8::ArrayBuffer::Allocator::Protection protection) { + if (this->_functions.SetProtection) { + auto super = [this](void *data, size_t length, + v8::ArrayBuffer::Allocator::Protection protection) { + return this->_fallback->SetProtection(data, length, protection); + }; + auto thunk = [](void *arg, void *data, size_t length, + v8::ArrayBuffer::Allocator::Protection protection) { + (*static_cast(arg))(data, length, protection); + }; + this->_functions.SetProtection(this->_self, thunk, &super, data, length, + protection); + } else { + this->_fallback->SetProtection(data, length, protection); + } + } + +private: + ArrayBufferAllocatorFunctions _functions; + void *_self; + v8::ArrayBuffer::Allocator *_fallback; +}; + +v8::ArrayBuffer::Allocator * +CreateArrayBufferAllocator(ArrayBufferAllocatorFunctions functions, + void *data) { + return new ArrayBufferAllocator( + functions, data, v8::ArrayBuffer::Allocator::NewDefaultAllocator()); +} + +void DestroyArrayBufferAllocator(v8::ArrayBuffer::Allocator *allocator) { + delete allocator; +} + +} // namespace rust_v8_impls diff --git a/v8-sys/src/isolate.cpp b/v8-sys/src/isolate.cpp new file mode 100644 index 00000000..66af483a --- /dev/null +++ b/v8-sys/src/isolate.cpp @@ -0,0 +1,13 @@ +#include "wrapper.hpp" + +void Isolate_SetData(v8::Isolate *self, uint32_t slot, void *data) { + self->SetData(slot, data); +} + +void *Isolate_GetData(v8::Isolate *self, uint32_t slot) { + return self->GetData(slot); +} + +uint32_t Isolate_GetNumberOfDataSlots() { + return v8::Isolate::GetNumberOfDataSlots(); +} diff --git a/v8-sys/src/lib.rs b/v8-sys/src/lib.rs index f527daa7..8e5ed0b0 100644 --- a/v8-sys/src/lib.rs +++ b/v8-sys/src/lib.rs @@ -1,11 +1,11 @@ +#![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#[cfg(test)] -#[macro_use] -extern crate lazy_static; +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); -include!(concat!(env!("OUT_DIR"), "/ffi.rs")); +#[doc(inline)] +pub use root::v8::*; -pub use ffi::*; +#[doc(inline)] +pub use root::rust_v8_impls as impls; diff --git a/v8-sys/src/platform.cpp b/v8-sys/src/platform.cpp new file mode 100644 index 00000000..f24ed402 --- /dev/null +++ b/v8-sys/src/platform.cpp @@ -0,0 +1,70 @@ +#include "wrapper.hpp" + +namespace rust_v8_impls { + +class Platform : public v8::Platform { +public: + Platform(PlatformFunctions functions, void *data) + : _functions(functions), _data(data) {} + + virtual ~Platform() { this->_functions.Destroy(this->_data); } + + virtual size_t NumberOfAvailableBackgroundThreads() { + return this->_functions.NumberOfAvailableBackgroundThreads(this->_data); + } + + virtual void + CallOnBackgroundThread(v8::Task *task, + v8::Platform::ExpectedRuntime expected_runtime) { + this->_functions.CallOnBackgroundThread(this->_data, task, + expected_runtime); + } + + virtual void CallOnForegroundThread(v8::Isolate *isolate, v8::Task *task) { + this->_functions.CallOnForegroundThread(this->_data, isolate, task); + } + + virtual void CallDelayedOnForegroundThread(v8::Isolate *isolate, + v8::Task *task, + double delay_in_seconds) { + this->_functions.CallDelayedOnForegroundThread(this->_data, isolate, task, + delay_in_seconds); + } + + virtual void CallIdleOnForegroundThread(v8::Isolate *isolate, + v8::IdleTask *task) { + this->_functions.CallIdleOnForegroundThread(this->_data, isolate, task); + } + + virtual bool IdleTasksEnabled(v8::Isolate *isolate) { + return this->_functions.IdleTasksEnabled(this->_data, isolate); + } + + virtual double MonotonicallyIncreasingTime() { + return this->_functions.MonotonicallyIncreasingTime(this->_data); + } + + virtual double CurrentClockTimeMillis() { + return 0.0; + } + + virtual v8::TracingController *GetTracingController() { + return nullptr; + } + +private: + PlatformFunctions _functions; + void *_data; +}; + +v8::Platform *CreatePlatform(PlatformFunctions functions, void *data) { + return new Platform(functions, data); +} + +void DestroyPlatform(v8::Platform *platform) { delete platform; } + +void DestroyTask(v8::Task *task) { delete task; } + +void DestroyIdleTask(v8::IdleTask *idle_task) { delete idle_task; } + +} // namespace rust_v8_impls diff --git a/v8-sys/src/v8-glue.cc b/v8-sys/src/v8-glue.cc deleted file mode 100644 index 506999dc..00000000 --- a/v8-sys/src/v8-glue.cc +++ /dev/null @@ -1,1230 +0,0 @@ -#include "v8-glue.h" - -#include -#include - - -template v8::Persistent *unwrap(v8::Isolate *isolate, - v8::Local value) -{ - if (value.IsEmpty()) { - return nullptr; - } else { - return new v8::Persistent(isolate, value); - } -} - -template v8::Persistent *unwrap(v8::Isolate *isolate, - v8::MaybeLocal value) -{ - v8::Local local; - - if (value.ToLocal(&local)) { - return new v8::Persistent(isolate, local); - } else { - return nullptr; - } -} - -#define UNWRAP_MAYBE_PRIM(PRIM, NAME, MAYBE) \ - MAYBE unwrap_maybe_##NAME( \ - v8::Isolate *isolate, \ - v8::Maybe maybe_value) \ - { \ - PRIM value; \ - bool is_set = maybe_value.To(&value); \ - \ - return MAYBE { \ - is_set, \ - value, \ - }; \ - } - -UNWRAP_MAYBE_PRIM(bool, bool, MaybeBool) -UNWRAP_MAYBE_PRIM(int, int, MaybeInt) -UNWRAP_MAYBE_PRIM(unsigned int, uint, MaybeUInt) -UNWRAP_MAYBE_PRIM(long, long, MaybeLong) -UNWRAP_MAYBE_PRIM(unsigned long, ulong, MaybeULong) -UNWRAP_MAYBE_PRIM(uint32_t, u32, MaybeU32) -UNWRAP_MAYBE_PRIM(int32_t, i32, MaybeI32) -UNWRAP_MAYBE_PRIM(uint64_t, u64, MaybeU64) -UNWRAP_MAYBE_PRIM(int64_t, i64, MaybeI64) -UNWRAP_MAYBE_PRIM(double, f64, MaybeF64) - -PropertyAttribute unwrap( - v8::Isolate *isolate, - v8::Maybe maybe_value) { - v8::PropertyAttribute value; - - if (maybe_value.To(&value)) { - PropertyAttribute result = PropertyAttribute_None; - - if (value & v8::PropertyAttribute::ReadOnly) { - result = PropertyAttribute(result | PropertyAttribute_ReadOnly); - } - - if (value & v8::PropertyAttribute::DontEnum) { - result = PropertyAttribute(result | PropertyAttribute_DontEnum); - } - - if (value & v8::PropertyAttribute::DontDelete) { - result = PropertyAttribute(result | PropertyAttribute_DontDelete); - } - - return result; - } else { - return PropertyAttribute_Absent; - } -} - -PromiseRejectEvent unwrap( - v8::Isolate *isolate, - v8::PromiseRejectEvent value) { - switch (value) { - default: - case v8::PromiseRejectEvent::kPromiseRejectWithNoHandler: - return PromiseRejectEvent_kPromiseRejectWithNoHandler; - case v8::kPromiseHandlerAddedAfterReject: - return PromiseRejectEvent_kPromiseHandlerAddedAfterReject; - } -} - -template A unwrap(v8::Isolate *isolate, A &&value) { - return value; -} - -template v8::Local wrap(v8::Isolate *isolate, - v8::Persistent *value) -{ - if (value) { - return value->Get(isolate); - } else { - return v8::Local(); - } -} - -v8::AccessControl wrap(v8::Isolate *isolate, AccessControl value) { - v8::AccessControl result = v8::AccessControl::DEFAULT; - - if (value & AccessControl_ALL_CAN_READ) { - result = v8::AccessControl(result | v8::AccessControl::ALL_CAN_READ); - } - - if (value & AccessControl_ALL_CAN_WRITE) { - result = v8::AccessControl(result | v8::AccessControl::ALL_CAN_WRITE); - } - - if (value & AccessControl_PROHIBITS_OVERWRITING) { - result = v8::AccessControl(result | v8::AccessControl::PROHIBITS_OVERWRITING); - } - - return result; -} - -v8::PropertyFilter wrap(v8::Isolate *isolate, PropertyFilter value) { - v8::PropertyFilter result = v8::PropertyFilter::ALL_PROPERTIES; - - if (value & PropertyFilter_ONLY_WRITABLE) { - result = v8::PropertyFilter(result | v8::PropertyFilter::ONLY_WRITABLE); - } - - if (value & PropertyFilter_ONLY_ENUMERABLE) { - result = v8::PropertyFilter(result | v8::PropertyFilter::ONLY_ENUMERABLE); - } - - if (value & PropertyFilter_ONLY_CONFIGURABLE) { - result = v8::PropertyFilter(result | v8::PropertyFilter::ONLY_CONFIGURABLE); - } - - if (value & PropertyFilter_SKIP_STRINGS) { - result = v8::PropertyFilter(result | v8::PropertyFilter::SKIP_STRINGS); - } - - if (value & PropertyFilter_SKIP_SYMBOLS) { - result = v8::PropertyFilter(result | v8::PropertyFilter::SKIP_SYMBOLS); - } - - return result; -} - -v8::KeyCollectionMode wrap(v8::Isolate *isolate, KeyCollectionMode value) { - switch (value) { - default: - case KeyCollectionMode_kOwnOnly: - return v8::KeyCollectionMode::kOwnOnly; - case KeyCollectionMode_kIncludePrototypes: - return v8::KeyCollectionMode::kIncludePrototypes; - } -} - -v8::IndexFilter wrap(v8::Isolate *isolate, IndexFilter value) { - switch (value) { - default: - case IndexFilter_kIncludeIndices: - return v8::IndexFilter::kIncludeIndices; - case IndexFilter_kSkipIndices: - return v8::IndexFilter::kSkipIndices; - } -} - -v8::IntegrityLevel wrap(v8::Isolate *isolate, IntegrityLevel value) { - switch (value) { - default: - case IntegrityLevel_kFrozen: - return v8::IntegrityLevel::kFrozen; - case IntegrityLevel_kSealed: - return v8::IntegrityLevel::kSealed; - } -} - -v8::PropertyAttribute wrap(v8::Isolate *isolate, PropertyAttribute value) { - if (value == PropertyAttribute_Absent) { - return v8::PropertyAttribute::None; - } - - v8::PropertyAttribute result = v8::PropertyAttribute::None; - - if (value & PropertyAttribute_ReadOnly) { - result = v8::PropertyAttribute(result | v8::PropertyAttribute::ReadOnly); - } - - if (value & PropertyAttribute_DontEnum) { - result = v8::PropertyAttribute(result | v8::PropertyAttribute::DontEnum); - } - - if (value & PropertyAttribute_DontDelete) { - result = v8::PropertyAttribute(result | v8::PropertyAttribute::DontDelete); - } - - return result; -} - -v8::PropertyHandlerFlags wrap(v8::Isolate *isolate, PropertyHandlerFlags value) { - v8::PropertyHandlerFlags result = v8::PropertyHandlerFlags::kNone; - - if (value & PropertyHandlerFlags_kAllCanRead) { - result = v8::PropertyHandlerFlags(int(result) | int(v8::PropertyHandlerFlags::kAllCanRead)); - } - - if (value & PropertyHandlerFlags_kNonMasking) { - result = v8::PropertyHandlerFlags(int(result) | int(v8::PropertyHandlerFlags::kNonMasking)); - } - - if (value & PropertyHandlerFlags_kOnlyInterceptStrings) { - result = v8::PropertyHandlerFlags(int(result) | int(v8::PropertyHandlerFlags::kOnlyInterceptStrings)); - } - - return result; -} - -v8::ConstructorBehavior wrap(v8::Isolate *isolate, ConstructorBehavior value) { - switch (value) { - default: - case ConstructorBehavior_kThrow: - return v8::ConstructorBehavior::kThrow; - case ConstructorBehavior_kAllow: - return v8::ConstructorBehavior::kAllow; - } -} - -v8::PromiseRejectEvent wrap(v8::Isolate *isolate, PromiseRejectEvent value) { - switch (value) { - default: - case PromiseRejectEvent_kPromiseRejectWithNoHandler: - return v8::PromiseRejectEvent::kPromiseRejectWithNoHandler; - case PromiseRejectEvent_kPromiseHandlerAddedAfterReject: - return v8::PromiseRejectEvent::kPromiseHandlerAddedAfterReject; - } -} - -v8::Intrinsic wrap(v8::Isolate *isolate, Intrinsic value) { - switch (value) { - default: -#define V8_SWITCH_INTRINSIC(name, iname) case Intrinsic_k##name: return v8::Intrinsic::k##name; - V8_INTRINSICS_LIST(V8_SWITCH_INTRINSIC) -#undef V8_SWITCH_INTRINSIC - } -} - -v8::ArrayBufferCreationMode wrap(v8::Isolate *isolate, ArrayBufferCreationMode value) { - switch (value) { - default: - case ArrayBufferCreationMode_kInternalized: - return v8::ArrayBufferCreationMode::kInternalized; - case ArrayBufferCreationMode_kExternalized: - return v8::ArrayBufferCreationMode::kExternalized; - } -} - -template -PropertyCallbackInfo build_callback_info( - const v8::PropertyCallbackInfo &info, - v8::Local data) { - - v8::Isolate *isolate = info.GetIsolate(); - - PropertyCallbackInfo result = PropertyCallbackInfo { - isolate, - unwrap(isolate, data), - unwrap(isolate, info.This()), - unwrap(isolate, info.Holder()), - nullptr, - info.ShouldThrowOnError(), - nullptr, - }; - - return result; -} - -template -FunctionCallbackInfo build_callback_info( - const v8::FunctionCallbackInfo &info, - v8::Local data) { - - v8::Isolate *isolate = info.GetIsolate(); - - int length = info.Length(); - ValueRef *args = new ValueRef[length]; - - for (int i = 0; i < length; i++) { - v8::Local arg = info[i]; - ValueRef unwrapped_arg = unwrap(isolate, arg); - args[i] = unwrapped_arg; - } - - FunctionCallbackInfo result = FunctionCallbackInfo { - length, - args, - unwrap(isolate, info.This()), - unwrap(isolate, info.Holder()), - unwrap(isolate, info.NewTarget()), - info.IsConstructCall(), - unwrap(isolate, data), - isolate, - nullptr, - nullptr, - }; - - return result; -} - -enum class PropertyHandlerFields { - Getter, Setter, Query, Deleter, Enumerator, Data, Flags, Max -}; - -void generic_named_property_handler_getter( - v8::Local property, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - GenericNamedPropertyGetterCallback getter = - (GenericNamedPropertyGetterCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Getter); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - getter(unwrap(isolate, property), &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(wrap(isolate, callback_info.ReturnValue)); - } -} - -void generic_named_property_handler_setter( - v8::Local property, - v8::Local value, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - GenericNamedPropertySetterCallback setter = - (GenericNamedPropertySetterCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Setter); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - setter(unwrap(isolate, property), unwrap(isolate, value), &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(wrap(isolate, callback_info.ReturnValue)); - } -} - -void generic_named_property_handler_query( - v8::Local property, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - GenericNamedPropertyQueryCallback query = - (GenericNamedPropertyQueryCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Query); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - query(unwrap(isolate, property), &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(v8::Local::Cast(wrap(isolate, callback_info.ReturnValue))); - } -} - -void generic_named_property_handler_deleter( - v8::Local property, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - GenericNamedPropertyDeleterCallback deleter = - (GenericNamedPropertyDeleterCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Deleter); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - deleter(unwrap(isolate, property), &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(v8::Local::Cast(wrap(isolate, callback_info.ReturnValue))); - } -} - -void generic_named_property_handler_enumerator( - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - GenericNamedPropertyEnumeratorCallback enumerator = - (GenericNamedPropertyEnumeratorCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Enumerator); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - enumerator(&callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(v8::Local::Cast(wrap(isolate, callback_info.ReturnValue))); - } -} - -v8::NamedPropertyHandlerConfiguration wrap( - v8::Isolate *isolate, - NamedPropertyHandlerConfiguration value) { - v8::Local outer_data_template = - v8::ObjectTemplate::New(isolate); - outer_data_template->SetInternalFieldCount((int) PropertyHandlerFields::Max); - v8::Local outer_data = outer_data_template->NewInstance(); - - v8::GenericNamedPropertyGetterCallback getter; - v8::GenericNamedPropertySetterCallback setter; - v8::GenericNamedPropertyQueryCallback query; - v8::GenericNamedPropertyDeleterCallback deleter; - v8::GenericNamedPropertyEnumeratorCallback enumerator; - - if (value.getter) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Getter, (void *) value.getter); - getter = generic_named_property_handler_getter; - } else { - getter = nullptr; - } - - if (value.setter) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Setter, (void *) value.setter); - setter = generic_named_property_handler_setter; - } else { - setter = nullptr; - } - - if (value.query) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Query, (void *) value.query); - query = generic_named_property_handler_query; - } else { - query = nullptr; - } - - if (value.deleter) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Deleter, (void *) value.deleter); - deleter = generic_named_property_handler_deleter; - } else { - deleter = nullptr; - } - - if (value.enumerator) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Enumerator, (void *) value.enumerator); - enumerator = generic_named_property_handler_enumerator; - } else { - enumerator = nullptr; - } - - outer_data->SetInternalField((int) PropertyHandlerFields::Data, wrap(isolate, value.data)); - - return v8::NamedPropertyHandlerConfiguration( - getter, - setter, - query, - deleter, - enumerator, - outer_data, - wrap(isolate, value.flags)); -} - -void indexed_property_handler_getter( - uint32_t index, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - IndexedPropertyGetterCallback getter = - (IndexedPropertyGetterCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Getter); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - getter(index, &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(wrap(isolate, callback_info.ReturnValue)); - } -} - -void indexed_property_handler_setter( - uint32_t index, - v8::Local value, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - IndexedPropertySetterCallback setter = - (IndexedPropertySetterCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Setter); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - setter(index, unwrap(isolate, value), &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(wrap(isolate, callback_info.ReturnValue)); - } -} - -void indexed_property_handler_query( - uint32_t index, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - IndexedPropertyQueryCallback query = - (IndexedPropertyQueryCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Query); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - query(index, &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(v8::Local::Cast(wrap(isolate, callback_info.ReturnValue))); - } -} - -void indexed_property_handler_deleter( - uint32_t index, - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - IndexedPropertyDeleterCallback deleter = - (IndexedPropertyDeleterCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Deleter); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - deleter(index, &callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(v8::Local::Cast(wrap(isolate, callback_info.ReturnValue))); - } -} - -void indexed_property_handler_enumerator( - const v8::PropertyCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - IndexedPropertyEnumeratorCallback enumerator = - (IndexedPropertyEnumeratorCallback) - outer_data->GetAlignedPointerFromInternalField((int) PropertyHandlerFields::Enumerator); - v8::Local data = outer_data->GetInternalField((int) PropertyHandlerFields::Data); - PropertyCallbackInfo callback_info = build_callback_info(info, data); - - enumerator(&callback_info); - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(v8::Local::Cast(wrap(isolate, callback_info.ReturnValue))); - } -} - -v8::IndexedPropertyHandlerConfiguration wrap( - v8::Isolate *isolate, - IndexedPropertyHandlerConfiguration value) { - v8::Local outer_data_template = - v8::ObjectTemplate::New(isolate); - outer_data_template->SetInternalFieldCount((int) PropertyHandlerFields::Max); - v8::Local outer_data = outer_data_template->NewInstance(); - - v8::IndexedPropertyGetterCallback getter; - v8::IndexedPropertySetterCallback setter; - v8::IndexedPropertyQueryCallback query; - v8::IndexedPropertyDeleterCallback deleter; - v8::IndexedPropertyEnumeratorCallback enumerator; - - if (value.getter) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Getter, (void *) value.getter); - getter = indexed_property_handler_getter; - } else { - getter = nullptr; - } - - if (value.setter) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Setter, (void *) value.setter); - setter = indexed_property_handler_setter; - } else { - setter = nullptr; - } - - if (value.query) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Query, (void *) value.query); - query = indexed_property_handler_query; - } else { - query = nullptr; - } - - if (value.deleter) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Deleter, (void *) value.deleter); - deleter = indexed_property_handler_deleter; - } else { - deleter = nullptr; - } - - if (value.enumerator) { - outer_data->SetAlignedPointerInInternalField((int) PropertyHandlerFields::Enumerator, (void *) value.enumerator); - enumerator = indexed_property_handler_enumerator; - } else { - enumerator = nullptr; - } - - outer_data->SetInternalField((int) PropertyHandlerFields::Data, wrap(isolate, value.data)); - - return v8::IndexedPropertyHandlerConfiguration( - getter, - setter, - query, - deleter, - enumerator, - outer_data, - wrap(isolate, value.flags)); -} - -template A wrap(v8::Isolate *isolate, A value) { - return value; -} - -void handle_exception(RustContext &c, v8::TryCatch &try_catch) { - if (try_catch.HasCaught()) { - *c.exception = unwrap(c.isolate, try_catch.Exception()); - *c.message = unwrap(c.isolate, try_catch.Message()); - } -} - -class GluePlatform : public v8::Platform { -public: - GluePlatform(v8_PlatformFunctions platform_functions) - : _platform_functions(platform_functions) - {} - - virtual ~GluePlatform() { - this->_platform_functions.Destroy(); - } - - virtual size_t NumberOfAvailableBackgroundThreads() { - return this->_platform_functions.NumberOfAvailableBackgroundThreads(); - } - - virtual void CallOnBackgroundThread(v8::Task *task, - v8::Platform::ExpectedRuntime expected_runtime) { - v8_ExpectedRuntime rt; - - switch (expected_runtime) { - default: - case v8::Platform::kShortRunningTask: - rt = SHORT_RUNNING_TASK; - break; - case v8::Platform::kLongRunningTask: - rt = LONG_RUNNING_TASK; - break; - } - - this->_platform_functions.CallOnBackgroundThread(task, rt); - } - - virtual void CallOnForegroundThread(v8::Isolate *isolate, v8::Task *task) { - this->_platform_functions.CallOnForegroundThread(isolate, task); - } - - virtual void CallDelayedOnForegroundThread(v8::Isolate *isolate, v8::Task *task, - double delay_in_seconds) { - this->_platform_functions.CallDelayedOnForegroundThread(isolate, task, delay_in_seconds); - } - - virtual void CallIdleOnForegroundThread(v8::Isolate *isolate, v8::IdleTask *task) { - this->_platform_functions.CallIdleOnForegroundThread(isolate, task); - } - - virtual bool IdleTasksEnabled(v8::Isolate *isolate) { - return this->_platform_functions.IdleTasksEnabled(isolate); - } - - virtual double MonotonicallyIncreasingTime() { - return this->_platform_functions.MonotonicallyIncreasingTime(); - } - -private: - v8_PlatformFunctions _platform_functions; -}; - -class GlueAllocator : public v8::ArrayBuffer::Allocator { -public: - GlueAllocator(v8_AllocatorFunctions allocator_functions) - : _allocator_functions(allocator_functions) - {} - - virtual void* Allocate(size_t length) { - return this->_allocator_functions.Allocate(length); - } - - virtual void* AllocateUninitialized(size_t length) { - return this->_allocator_functions.AllocateUninitialized(length); - } - - virtual void Free(void* data, size_t length) { - this->_allocator_functions.Free(data, length); - } - -private: - v8_AllocatorFunctions _allocator_functions; -}; - -PlatformPtr v8_Platform_Create(struct v8_PlatformFunctions platform_functions) { - return new GluePlatform(platform_functions); -} - -void v8_Platform_Destroy(PlatformPtr platform) { - delete platform; -} - -void v8_Task_Destroy(TaskPtr task) { - delete task; -} - -void v8_IdleTask_Destroy(IdleTaskPtr idle_task) { - delete idle_task; -} - -void v8_V8_InitializePlatform(PlatformPtr platform) { - return v8::V8::InitializePlatform(platform); -} - -void v8_V8_InitializeICU() { - v8::V8::InitializeICU(); -} - -void v8_V8_Initialize() { - v8::V8::Initialize(); -} - -void v8_V8_Dispose() { - v8::V8::Dispose(); -} - -void v8_V8_ShutdownPlatform() { - v8::V8::ShutdownPlatform(); -} - - -ArrayBuffer_AllocatorPtr v8_ArrayBuffer_Allocator_Create(struct v8_AllocatorFunctions allocator_functions) { - return new GlueAllocator(allocator_functions); - -} -void v8_ArrayBuffer_Allocator_Destroy(ArrayBuffer_AllocatorPtr allocator) { - delete allocator; -} - -IsolatePtr v8_Isolate_New(ArrayBuffer_AllocatorPtr allocator) { - auto params = v8::Isolate::CreateParams(); - params.array_buffer_allocator = allocator; - return v8::Isolate::New(params); -} - -uint32_t v8_Isolate_GetNumberOfDataSlots(IsolatePtr self) { - return self->GetNumberOfDataSlots(); -} - -void v8_Isolate_SetData(IsolatePtr self, uint32_t slot, void *data) { - self->SetData(slot, data); -} - -void *v8_Isolate_GetData(IsolatePtr self, uint32_t slot) { - return self->GetData(slot); -} - -ContextRef v8_Isolate_GetCurrentContext(IsolatePtr self) { - return unwrap(self, self->GetCurrentContext()); -} - -ValueRef v8_Isolate_ThrowException(IsolatePtr self, ValueRef exception) { - return unwrap(self, self->ThrowException(wrap(self, exception))); -} - -void v8_Isolate_SetCaptureStackTraceForUncaughtExceptions_Overview(IsolatePtr self, bool capture, int frame_limit) { - self->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit, v8::StackTrace::kOverview); -} - -void v8_Isolate_SetCaptureStackTraceForUncaughtExceptions_Detailed(IsolatePtr self, bool capture, int frame_limit) { - self->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit, v8::StackTrace::kDetailed); -} - -void v8_Isolate_Dispose(IsolatePtr isolate) { - isolate->Dispose(); -} - -void v8_Task_Run(TaskPtr task) { - task->Run(); -} - -void v8_IdleTask_Run(IdleTaskPtr task, double deadline_in_seconds) { - task->Run(deadline_in_seconds); -} - -#include "v8-glue-generated.cc" - -PrimitiveRef v8_Undefined(RustContext c) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::Undefined(c.isolate); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -PrimitiveRef v8_Null(RustContext c) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::Null(c.isolate); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -BooleanRef v8_True(RustContext c) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::True(c.isolate); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -BooleanRef v8_False(RustContext c) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::False(c.isolate); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -ContextRef v8_Context_New(RustContext c) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::Context::New(c.isolate); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -StringRef v8_String_NewFromUtf8_Normal(RustContext c, const char *data, int length) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::String::NewFromUtf8(c.isolate, data, v8::NewStringType::kNormal, length); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -StringRef v8_String_NewFromUtf8_Internalized(RustContext c, const char *data, int length) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = v8::String::NewFromUtf8(c.isolate, data, v8::NewStringType::kInternalized, length); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -int v8_String_WriteUtf8(RustContext c, StringRef string, char *buffer, int length) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - auto result = wrap(c.isolate, string)->WriteUtf8(buffer, length); - handle_exception(c, try_catch); - return result; -} - -ScriptRef v8_Script_Compile(RustContext c, ContextRef context, StringRef source) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Context::Scope context_scope(wrap(c.isolate, context)); - auto result = v8::Script::Compile(wrap(c.isolate, context), wrap(c.isolate, source)); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - - -ScriptRef v8_Script_Compile_Origin( - RustContext c, - ContextRef context, - StringRef source, - ValueRef resource_name, - IntegerRef resource_line_offset, - IntegerRef resource_column_offset, - BooleanRef resource_is_shared_cross_origin, - IntegerRef script_id, - BooleanRef resource_is_embedder_debug_script, - ValueRef source_map_url, - BooleanRef resource_is_opaque) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Context::Scope context_scope(wrap(c.isolate, context)); - - v8::ScriptOrigin origin( - wrap(c.isolate, resource_name), - wrap(c.isolate, resource_line_offset), - wrap(c.isolate, resource_column_offset), - wrap(c.isolate, resource_is_shared_cross_origin), - wrap(c.isolate, script_id), - #if V8_MAJOR_VERSION < 5 || (V8_MAJOR_VERSION == 5 && V8_MINOR_VERSION < 7) - wrap(c.isolate, resource_is_embedder_debug_script), - #endif - wrap(c.isolate, source_map_url), - wrap(c.isolate, resource_is_opaque)); - - auto result = v8::Script::Compile( - wrap(c.isolate, context), - wrap(c.isolate, source), - &origin); - - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -ValueRef v8_Object_CallAsFunction(RustContext c, ObjectRef self, ContextRef context, ValueRef recv, int argc, ValueRef argv[]) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Context::Scope context_scope(wrap(c.isolate, context)); - v8::Local *argv_wrapped = static_cast*>(alloca(sizeof(v8::Local) * argc)); - v8::Local recv_wrapped; - - for (int i = 0; i < argc; i++) { - argv_wrapped[i] = wrap(c.isolate, argv[i]); - } - - if (recv == nullptr) { - recv_wrapped = v8::Undefined(c.isolate); - } else { - recv_wrapped = wrap(c.isolate, recv); - } - - auto result = wrap(c.isolate, self)->CallAsFunction(wrap(c.isolate, context), recv_wrapped, argc, argv_wrapped); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -ValueRef v8_Object_CallAsConstructor(RustContext c, ObjectRef self, ContextRef context, int argc, ValueRef argv[]) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Context::Scope context_scope(wrap(c.isolate, context)); - v8::Local *argv_wrapped = static_cast*>(alloca(sizeof(v8::Local) * argc)); - - for (int i = 0; i < argc; i++) { - argv_wrapped[i] = wrap(c.isolate, argv[i]); - } - - auto result = wrap(c.isolate, self)->CallAsConstructor(wrap(c.isolate, context), argc, argv_wrapped); - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -enum class FunctionHandlerFields { - Callback, Data, Max -}; - - -void function_callback(const v8::FunctionCallbackInfo &info) { - v8::Isolate *isolate = info.GetIsolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local outer_data = - v8::Local::Cast(info.Data()); - - FunctionCallback callback = - (FunctionCallback) - outer_data->GetAlignedPointerFromInternalField((int) FunctionHandlerFields::Callback); - v8::Local data = outer_data->GetInternalField((int) FunctionHandlerFields::Data); - FunctionCallbackInfo callback_info = build_callback_info(info, data); - - callback(&callback_info); - - delete[] callback_info.Args; - - if (callback_info.ThrownValue) { - isolate->ThrowException(wrap(isolate, callback_info.ThrownValue)); - } else if (callback_info.ReturnValue) { - info.GetReturnValue().Set(wrap(isolate, callback_info.ReturnValue)); - } -} - -FunctionRef v8_Function_New( - RustContext c, - ContextRef context, - FunctionCallback wrapped_callback, - ValueRef data, - int length, - ConstructorBehavior behavior) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Local outer_data_template = - v8::ObjectTemplate::New(c.isolate); - outer_data_template->SetInternalFieldCount((int) FunctionHandlerFields::Max); - v8::Local outer_data = - outer_data_template->NewInstance(wrap(c.isolate, context)).ToLocalChecked(); - - v8::FunctionCallback callback; - - if (wrapped_callback) { - outer_data->SetAlignedPointerInInternalField((int) FunctionHandlerFields::Callback, (void *) wrapped_callback); - callback = function_callback; - } else { - callback = nullptr; - } - - outer_data->SetInternalField((int) FunctionHandlerFields::Data, wrap(c.isolate, data)); - - auto result = v8::Function::New(wrap(c.isolate, context), callback, outer_data, length, wrap(c.isolate, behavior)); - - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -ObjectRef v8_Function_NewInstance( - RustContext c, - FunctionRef self, - ContextRef context, - int argc, - ValueRef argv[]) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Context::Scope context_scope(wrap(c.isolate, context)); - - v8::Local *argv_wrapped = static_cast*>(alloca(sizeof(v8::Local) * argc)); - - for (int i = 0; i < argc; i++) { - argv_wrapped[i] = wrap(c.isolate, argv[i]); - } - - auto result = wrap(c.isolate, self)->NewInstance(wrap(c.isolate, context), argc, argv_wrapped); - - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -ValueRef v8_Function_Call( - RustContext c, - FunctionRef self, - ContextRef context, - ValueRef recv, - int argc, - ValueRef argv[]) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Context::Scope context_scope(wrap(c.isolate, context)); - - v8::Local *argv_wrapped = static_cast*>(alloca(sizeof(v8::Local) * argc)); - v8::Local recv_wrapped; - - for (int i = 0; i < argc; i++) { - argv_wrapped[i] = wrap(c.isolate, argv[i]); - } - - if (recv == nullptr) { - recv_wrapped = v8::Undefined(c.isolate); - } else { - recv_wrapped = wrap(c.isolate, recv); - } - - auto result = wrap(c.isolate, self)->Call(wrap(c.isolate, context), recv_wrapped, argc, argv_wrapped); - - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -void v8_Template_SetNativeDataProperty( - RustContext c, - TemplateRef self, - StringRef name, - AccessorGetterCallback getter, - AccessorSetterCallback setter, - ValueRef data, - PropertyAttribute attribute, - AccessorSignatureRef signature, - AccessControl settings) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - - handle_exception(c, try_catch); -} - -FunctionTemplateRef v8_FunctionTemplate_New( - RustContext c, - ContextRef context, - FunctionCallback wrapped_callback, - ValueRef data, - SignatureRef signature, - int length, - ConstructorBehavior behavior) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - v8::Local outer_data_template = - v8::ObjectTemplate::New(c.isolate); - outer_data_template->SetInternalFieldCount((int) FunctionHandlerFields::Max); - v8::Local outer_data = - outer_data_template->NewInstance(wrap(c.isolate, context)).ToLocalChecked(); - - v8::FunctionCallback callback; - - if (wrapped_callback) { - outer_data->SetAlignedPointerInInternalField((int) FunctionHandlerFields::Callback, (void *) wrapped_callback); - callback = function_callback; - } - - outer_data->SetInternalField((int) FunctionHandlerFields::Data, wrap(c.isolate, data)); - - auto result = v8::FunctionTemplate::New(c.isolate, callback, outer_data, wrap(c.isolate, signature), length, wrap(c.isolate, behavior)); - - handle_exception(c, try_catch); - return unwrap(c.isolate, result); -} - -void v8_ObjectTemplate_SetAccessor( - RustContext c, - ObjectTemplateRef self, - StringRef name, - AccessorGetterCallback getter, - AccessorSetterCallback setter, - ValueRef data, - AccessControl settings, - PropertyAttribute attribute, - AccessorSignatureRef signature) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - - handle_exception(c, try_catch); -} - -void v8_ObjectTemplate_SetAccessor_Name( - RustContext c, - ObjectTemplateRef self, - StringRef name, - AccessorNameGetterCallback getter, - AccessorNameSetterCallback setter, - ValueRef data, - AccessControl settings, - PropertyAttribute attribute, - AccessorSignatureRef signature) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - - handle_exception(c, try_catch); -} - -void v8_ObjectTemplate_SetCallAsFunctionHandler( - RustContext c, - ObjectTemplateRef self, - FunctionCallback callback, - ValueRef data) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - - handle_exception(c, try_catch); -} - -void v8_ObjectTemplate_SetAccessCheckCallback( - RustContext c, - ObjectTemplateRef self, - AccessCheckCallback callback, - ValueRef data) { - v8::Isolate::Scope isolate_scope(c.isolate); - v8::HandleScope scope(c.isolate); - v8::TryCatch try_catch(c.isolate); - - handle_exception(c, try_catch); -} diff --git a/v8-sys/src/v8-glue.h b/v8-sys/src/v8-glue.h deleted file mode 100644 index 8cc4f59d..00000000 --- a/v8-sys/src/v8-glue.h +++ /dev/null @@ -1,404 +0,0 @@ -#if defined __cplusplus - -#include -#include - -extern "C" { -#else - -#include -#include -#include - -#endif /* defined __cplusplus */ - -/* A context passed in from Rust that handles isolation and exception - handling. - */ -struct RustContext; -typedef struct RustContext RustContext; - -/* Structs for "maybes" containing primitives */ -#define STRUCT_MAYBE_PRIM(PRIM, SUFFIX) \ - struct Maybe##SUFFIX { \ - bool is_set; \ - PRIM value; \ - }; \ - typedef struct Maybe##SUFFIX Maybe##SUFFIX; - -STRUCT_MAYBE_PRIM(bool, Bool); -STRUCT_MAYBE_PRIM(unsigned int, UInt); -STRUCT_MAYBE_PRIM(int, Int); -STRUCT_MAYBE_PRIM(unsigned long, ULong); -STRUCT_MAYBE_PRIM(long, Long); -STRUCT_MAYBE_PRIM(double, F64); -STRUCT_MAYBE_PRIM(uint32_t, U32); -STRUCT_MAYBE_PRIM(int32_t, I32); -STRUCT_MAYBE_PRIM(uint64_t, U64); -STRUCT_MAYBE_PRIM(int64_t, I64); - -/* Very special classes that we don't want to auto-map. */ -#if defined __cplusplus -typedef v8::ArrayBuffer::Allocator *ArrayBuffer_AllocatorPtr; -#else -typedef struct _ArrayBuffer_Allocator *ArrayBuffer_AllocatorPtr; -#endif /* defined __cplusplus */ - -#if defined __cplusplus -typedef v8::Isolate *IsolatePtr; -#else -typedef struct _Isolate *IsolatePtr; -#endif /* defined __cplusplus */ - -#if defined __cplusplus -typedef v8::Platform *PlatformPtr; -#else -typedef struct _Platform *PlatformPtr; -#endif /* defined __cplusplus */ - -#if defined __cplusplus -typedef v8::Task *TaskPtr; -#else -typedef struct _Task *TaskPtr; -#endif /* defined __cplusplus */ - -#if defined __cplusplus -typedef v8::IdleTask *IdleTaskPtr; -#else -typedef struct _IdleTask *IdleTaskPtr; -#endif /* defined __cplusplus */ - -/* Special structs simulating vtables */ -struct v8_AllocatorFunctions { - void *(*Allocate)(size_t length); - void *(*AllocateUninitialized)(size_t length); - void (*Free)(void *data, size_t length); -}; -typedef struct v8_AllocatorFunctions v8_AllocatorFunctions; - -enum v8_ExpectedRuntime { - SHORT_RUNNING_TASK, - LONG_RUNNING_TASK, -}; - -struct v8_PlatformFunctions { - void (*Destroy)(); - size_t (*NumberOfAvailableBackgroundThreads)(); - void (*CallOnBackgroundThread)(TaskPtr task, enum v8_ExpectedRuntime expected_runtime); - void (*CallOnForegroundThread)(IsolatePtr isolate, TaskPtr task); - void (*CallDelayedOnForegroundThread)(IsolatePtr isolate, TaskPtr task, double delay_in_seconds); - void (*CallIdleOnForegroundThread)(IsolatePtr isolate, IdleTaskPtr task); - bool (*IdleTasksEnabled)(IsolatePtr isolate); - double (*MonotonicallyIncreasingTime)(); -}; -typedef struct v8_PlatformFunctions v8_PlatformFunctions; - -/* Copy-paste of enums */ - -enum AccessControl { - AccessControl_DEFAULT = 0, - AccessControl_ALL_CAN_READ = 1, - AccessControl_ALL_CAN_WRITE = 1 << 1, - AccessControl_PROHIBITS_OVERWRITING = 1 << 2 -}; -typedef enum AccessControl AccessControl; - -enum PropertyFilter { - PropertyFilter_ALL_PROPERTIES = 0, - PropertyFilter_ONLY_WRITABLE = 1, - PropertyFilter_ONLY_ENUMERABLE = 2, - PropertyFilter_ONLY_CONFIGURABLE = 4, - PropertyFilter_SKIP_STRINGS = 8, - PropertyFilter_SKIP_SYMBOLS = 16 -}; -typedef enum PropertyFilter PropertyFilter; - -enum KeyCollectionMode { - KeyCollectionMode_kOwnOnly, - KeyCollectionMode_kIncludePrototypes -}; -typedef enum KeyCollectionMode KeyCollectionMode; - -enum IndexFilter { - IndexFilter_kIncludeIndices, - IndexFilter_kSkipIndices -}; -typedef enum IndexFilter IndexFilter; - -enum IntegrityLevel { - IntegrityLevel_kFrozen, - IntegrityLevel_kSealed -}; -typedef enum IntegrityLevel IntegrityLevel; - -enum PropertyAttribute { - PropertyAttribute_Absent = -1, /* Instead of Maybe */ - PropertyAttribute_None = 0, - PropertyAttribute_ReadOnly = 1 << 0, - PropertyAttribute_DontEnum = 1 << 1, - PropertyAttribute_DontDelete = 1 << 2, -}; -typedef enum PropertyAttribute PropertyAttribute; - -enum PropertyHandlerFlags { - PropertyHandlerFlags_kNone = 0, - PropertyHandlerFlags_kAllCanRead = 1, - PropertyHandlerFlags_kNonMasking = 1 << 1, - PropertyHandlerFlags_kOnlyInterceptStrings = 1 << 2, -}; -typedef enum PropertyHandlerFlags PropertyHandlerFlags; - -enum ConstructorBehavior { - ConstructorBehavior_kThrow, - ConstructorBehavior_kAllow -}; -typedef enum ConstructorBehavior ConstructorBehavior; - -enum PromiseRejectEvent { - PromiseRejectEvent_kPromiseRejectWithNoHandler = 0, - PromiseRejectEvent_kPromiseHandlerAddedAfterReject = 1 -}; -typedef enum PromiseRejectEvent PromiseRejectEvent; - -#define V8_INTRINSICS_LIST(F) F(ArrayProto_values, array_values_iterator) - -enum Intrinsic { -#define V8_DECL_INTRINSIC(name, iname) Intrinsic_k##name, - V8_INTRINSICS_LIST(V8_DECL_INTRINSIC) -#undef V8_DECL_INTRINSIC -}; -typedef enum Intrinsic Intrinsic; - -enum ArrayBufferCreationMode { - ArrayBufferCreationMode_kInternalized, - ArrayBufferCreationMode_kExternalized -}; -typedef enum ArrayBufferCreationMode ArrayBufferCreationMode; - -/* Auto-generated forward declarations for class pointers */ -#include "v8-glue-decl-generated.h" - -struct PropertyCallbackInfo { - IsolatePtr GetIsolate; - ValueRef Data; - ObjectRef This; - ObjectRef Holder; - ValueRef ReturnValue; - bool ShouldThrowOnError; - ValueRef ThrownValue; -}; - -struct FunctionCallbackInfo { - int Length; - ValueRef *Args; - ObjectRef This; - ObjectRef Holder; - ValueRef NewTarget; - bool IsConstructCall; - ValueRef Data; - IsolatePtr GetIsolate; - ValueRef ReturnValue; - ValueRef ThrownValue; -}; - -/* These typedefs are just here to give a nicer hint to the user as to - which type of return value is expected to be set. For the `Void` - variant, the SetReturnValue function should not be called. -*/ - -typedef struct PropertyCallbackInfo *PropertyCallbackInfoPtr_Void; -typedef struct PropertyCallbackInfo *PropertyCallbackInfoPtr_Value; -typedef struct PropertyCallbackInfo *PropertyCallbackInfoPtr_Boolean; -typedef struct PropertyCallbackInfo *PropertyCallbackInfoPtr_Integer; -typedef struct PropertyCallbackInfo *PropertyCallbackInfoPtr_Array; -typedef struct FunctionCallbackInfo *FunctionCallbackInfoPtr_Value; - -typedef void (*AccessorGetterCallback)( - StringRef property, - PropertyCallbackInfoPtr_Value info); - -typedef void (*AccessorNameGetterCallback)( - NameRef property, - PropertyCallbackInfoPtr_Value info); - -typedef void (*AccessorSetterCallback)( - StringRef property, - ValueRef value, - PropertyCallbackInfoPtr_Void info); - -typedef void (*AccessorNameSetterCallback)( - NameRef property, - ValueRef value, - PropertyCallbackInfoPtr_Void info); - -typedef void (*FunctionCallback)( - FunctionCallbackInfoPtr_Value info); - -typedef void (*NamedPropertyGetterCallback)( - StringRef property, - PropertyCallbackInfoPtr_Value info); - -typedef void (*NamedPropertySetterCallback)( - StringRef property, - ValueRef value, - PropertyCallbackInfoPtr_Value info); - -typedef void (*NamedPropertyQueryCallback)( - StringRef property, - PropertyCallbackInfoPtr_Integer info); - -typedef void (*NamedPropertyDeleterCallback)( - StringRef property, - PropertyCallbackInfoPtr_Boolean info); - -typedef void (*NamedPropertyEnumeratorCallback)( - PropertyCallbackInfoPtr_Array info); - -typedef void (*GenericNamedPropertyGetterCallback)( - NameRef property, - PropertyCallbackInfoPtr_Value info); - -typedef void (*GenericNamedPropertySetterCallback)( - NameRef property, - ValueRef value, - PropertyCallbackInfoPtr_Value info); - -typedef void (*GenericNamedPropertyQueryCallback)( - NameRef property, - PropertyCallbackInfoPtr_Integer info); - -typedef void (*GenericNamedPropertyDeleterCallback)( - NameRef property, - PropertyCallbackInfoPtr_Boolean info); - -typedef void (*GenericNamedPropertyEnumeratorCallback)( - PropertyCallbackInfoPtr_Array info); - -typedef void (*IndexedPropertyGetterCallback)( - uint32_t index, - PropertyCallbackInfoPtr_Value info); - -typedef void (*IndexedPropertySetterCallback)( - uint32_t index, - ValueRef value, - PropertyCallbackInfoPtr_Value info); - -typedef void (*IndexedPropertyQueryCallback)( - uint32_t index, - PropertyCallbackInfoPtr_Integer info); - -typedef void (*IndexedPropertyDeleterCallback)( - uint32_t index, - PropertyCallbackInfoPtr_Boolean info); - -typedef void (*IndexedPropertyEnumeratorCallback)( - PropertyCallbackInfoPtr_Array info); - -typedef bool (*AccessCheckCallback)( - ContextRef accessing_context, - ObjectRef accessed_object, - ValueRef data); - -typedef void (*FatalErrorCallback)( - const char *location, - const char *message); - -typedef void (*OOMErrorCallback)( - const char *location, - bool is_heap_oom); - -struct NamedPropertyHandlerConfiguration { - GenericNamedPropertyGetterCallback getter; - GenericNamedPropertySetterCallback setter; - GenericNamedPropertyQueryCallback query; - GenericNamedPropertyDeleterCallback deleter; - GenericNamedPropertyEnumeratorCallback enumerator; - ValueRef data; - PropertyHandlerFlags flags; -}; -typedef struct NamedPropertyHandlerConfiguration NamedPropertyHandlerConfiguration; - -struct IndexedPropertyHandlerConfiguration { - IndexedPropertyGetterCallback getter; - IndexedPropertySetterCallback setter; - IndexedPropertyQueryCallback query; - IndexedPropertyDeleterCallback deleter; - IndexedPropertyEnumeratorCallback enumerator; - ValueRef data; - PropertyHandlerFlags flags; -}; -typedef struct IndexedPropertyHandlerConfiguration IndexedPropertyHandlerConfiguration; - - -PlatformPtr v8_Platform_Create(v8_PlatformFunctions platform_functions); -void v8_Platform_Destroy(PlatformPtr platform); - -void v8_Task_Destroy(TaskPtr task); -void v8_IdleTask_Destroy(IdleTaskPtr task); - -void v8_V8_InitializeICU(); -void v8_V8_InitializePlatform(PlatformPtr platform); -void v8_V8_Initialize(); -void v8_V8_Dispose(); -void v8_V8_ShutdownPlatform(); - - -ArrayBuffer_AllocatorPtr v8_ArrayBuffer_Allocator_Create(v8_AllocatorFunctions allocator_functions); -void v8_ArrayBuffer_Allocator_Destroy(ArrayBuffer_AllocatorPtr allocator); - -IsolatePtr v8_Isolate_New(ArrayBuffer_AllocatorPtr allocator); -ContextRef v8_Isolate_GetCurrentContext(IsolatePtr self); -ValueRef v8_Isolate_ThrowException(IsolatePtr self, ValueRef exception); -uint32_t v8_Isolate_GetNumberOfDataSlots(IsolatePtr self); -void v8_Isolate_SetData(IsolatePtr self, uint32_t slot, void *data); -void *v8_Isolate_GetData(IsolatePtr self, uint32_t slot); -void v8_Isolate_SetCaptureStackTraceForUncaughtExceptions_Overview(IsolatePtr self, bool capture, int frame_limit); -void v8_Isolate_SetCaptureStackTraceForUncaughtExceptions_Detailed(IsolatePtr self, bool capture, int frame_limit); -void v8_Isolate_Dispose(IsolatePtr isolate); - -void v8_Task_Run(TaskPtr task); -void v8_IdleTask_Run(IdleTaskPtr task, double deadline_in_seconds); - -#include "v8-glue-generated.h" - -PrimitiveRef v8_Undefined(RustContext c); -PrimitiveRef v8_Null(RustContext c); -BooleanRef v8_True(RustContext c); -BooleanRef v8_False(RustContext c); - -ContextRef v8_Context_New(RustContext c); - -StringRef v8_String_NewFromUtf8_Normal(RustContext c, const char *data, int length); -StringRef v8_String_NewFromUtf8_Internalized(RustContext c, const char *data, int length); - -int v8_String_WriteUtf8(RustContext c, StringRef string, char *buffer, int length); - -ScriptRef v8_Script_Compile(RustContext c, ContextRef context, StringRef source); -ScriptRef v8_Script_Compile_Origin(RustContext c, ContextRef context, StringRef source, ValueRef resource_name, IntegerRef resource_line_offset, IntegerRef resource_column_offset, BooleanRef resource_is_shared_cross_origin, IntegerRef script_id, BooleanRef resource_is_embedder_debug_script, ValueRef source_map_url, BooleanRef resource_is_opaque); - -ValueRef v8_Object_CallAsFunction(RustContext c, ObjectRef self, ContextRef context, ValueRef recv, int argc, ValueRef argv[]); - -ValueRef v8_Object_CallAsConstructor(RustContext c, ObjectRef self, ContextRef context, int argc, ValueRef argv[]); - -FunctionRef v8_Function_New(RustContext c, ContextRef context, FunctionCallback callback, ValueRef data, int length, ConstructorBehavior behavior); -ObjectRef v8_Function_NewInstance(RustContext c, FunctionRef self, ContextRef context, int argc, ValueRef argv[]); -ValueRef v8_Function_Call(RustContext c, FunctionRef self, ContextRef context, ValueRef recv, int argc, ValueRef argv[]); - -void v8_Template_SetNativeDataProperty(RustContext c, TemplateRef self, StringRef name, AccessorGetterCallback getter, AccessorSetterCallback setter, ValueRef data, PropertyAttribute attribute, AccessorSignatureRef signature, AccessControl settings); - -FunctionTemplateRef v8_FunctionTemplate_New(RustContext c, ContextRef context, FunctionCallback wrapped_callback, ValueRef data, SignatureRef signature, int length, ConstructorBehavior behavior); - -void v8_ObjectTemplate_SetAccessor(RustContext c, ObjectTemplateRef self, StringRef name, AccessorGetterCallback getter, AccessorSetterCallback setter, ValueRef data, AccessControl settings, PropertyAttribute attribute, AccessorSignatureRef signature); -void v8_ObjectTemplate_SetAccessor_Name(RustContext c, ObjectTemplateRef self, StringRef name, AccessorNameGetterCallback getter, AccessorNameSetterCallback setter, ValueRef data, AccessControl settings, PropertyAttribute attribute, AccessorSignatureRef signature); -void v8_ObjectTemplate_SetCallAsFunctionHandler(RustContext c, ObjectTemplateRef self, FunctionCallback callback, ValueRef data); -void v8_ObjectTemplate_SetAccessCheckCallback(RustContext c, ObjectTemplateRef self, AccessCheckCallback callback, ValueRef data); - -struct RustContext { - IsolatePtr isolate; - ValueRef *exception; - MessageRef *message; -}; - -#if defined __cplusplus -} /* extern "C" */ -#endif /* defined __cplusplus */ diff --git a/v8-sys/src/v8-trampoline.h b/v8-sys/src/v8-trampoline.h deleted file mode 100644 index 61fd3efd..00000000 --- a/v8-sys/src/v8-trampoline.h +++ /dev/null @@ -1,4 +0,0 @@ -// v8-trampoline.h: includes the files containing the V8 APIs we want -// to wrap. -#include -#include diff --git a/v8-sys/src/wrapper.hpp b/v8-sys/src/wrapper.hpp new file mode 100644 index 00000000..1bb07bca --- /dev/null +++ b/v8-sys/src/wrapper.hpp @@ -0,0 +1,49 @@ +#include +#include + +namespace rust_v8_impls { + +struct ArrayBufferAllocatorFunctions { + void (*Destroy)(void *, void (*)(void *), void *); + void *(*Allocate)(void *, void *(*)(void *, size_t), void *, size_t); + void *(*AllocateUninitialized)(void *, void *(*)(void *, size_t), void *, + size_t); + void *(*Reserve)(void *, void *(*)(void *, size_t), void *, size_t); + void (*Free)(void *, void (*)(void *, void *, size_t), void *, void *, + size_t); + void (*FreeMode)(void *, + void (*)(void *, void *, size_t, + v8::ArrayBuffer::Allocator::AllocationMode), + void *, void *, size_t, + v8::ArrayBuffer::Allocator::AllocationMode); + void (*SetProtection)(void *, + void (*)(void *, void *, size_t, + v8::ArrayBuffer::Allocator::Protection), + void *, void *, size_t, + v8::ArrayBuffer::Allocator::Protection); +}; + +struct PlatformFunctions { + void (*Destroy)(void *); + size_t (*NumberOfAvailableBackgroundThreads)(void *); + void (*CallOnBackgroundThread)(void *, v8::Task *, + v8::Platform::ExpectedRuntime); + void (*CallOnForegroundThread)(void *, v8::Isolate *, v8::Task *); + void (*CallDelayedOnForegroundThread)(void *, v8::Isolate *, v8::Task *, + double); + void (*CallIdleOnForegroundThread)(void *, v8::Isolate *, v8::IdleTask *); + bool (*IdleTasksEnabled)(void *, v8::Isolate *); + double (*MonotonicallyIncreasingTime)(void *); +}; + +v8::ArrayBuffer::Allocator * +CreateArrayBufferAllocator(ArrayBufferAllocatorFunctions functions, void *data); + +v8::Platform *CreatePlatform(PlatformFunctions functions, void *data); + +/** + *

+ */ +typedef void JitCodeEvent; + +} // namespace rust_v8_impls