From e89a968ff2120c2bb1131918173dae8be4ef93fb Mon Sep 17 00:00:00 2001 From: Ry Dahl Date: Fri, 20 Dec 2019 08:47:20 -0500 Subject: [PATCH] add more docs and clean up exception, json modules (#92) --- src/context.rs | 9 +++++ src/exception.rs | 86 +++++++++++++++++++++-------------------------- src/isolate.rs | 16 ++++++--- src/json.rs | 43 ++++++++++-------------- src/lib.rs | 6 ++-- src/locker.rs | 17 ++++------ tests/test_api.rs | 18 +++++----- 7 files changed, 95 insertions(+), 100 deletions(-) diff --git a/src/context.rs b/src/context.rs index 51f247af..6ded92a7 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,3 +1,4 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. use crate::isolate::Isolate; use crate::support::Opaque; use crate::Local; @@ -11,6 +12,8 @@ extern "C" { fn v8__Context__Global(this: *mut Context) -> *mut Object; } +/// A sandboxed execution context with its own set of built-in objects and +/// functions. #[repr(C)] pub struct Context(Opaque); @@ -34,11 +37,17 @@ impl Context { unsafe { Local::from_raw(v8__Context__Global(&mut *self)).unwrap() } } + /// Enter this context. After entering a context, all code compiled + /// and run is compiled and run in this context. If another context + /// is already entered, this old context is saved so it can be + /// restored when the new context is exited. pub fn enter(&mut self) { // TODO: enter/exit should be controlled by a scope. unsafe { v8__Context__Enter(self) }; } + /// Exit this context. Exiting the current context restores the + /// context that was in place when entering the current context. pub fn exit(&mut self) { // TODO: enter/exit should be controlled by a scope. unsafe { v8__Context__Exit(self) }; diff --git a/src/exception.rs b/src/exception.rs index 7c918bf1..c57783f7 100644 --- a/src/exception.rs +++ b/src/exception.rs @@ -54,52 +54,44 @@ impl Message { } } -/// Create new error objects by calling the corresponding error object -/// constructor with the message. -pub mod Exception { - use super::*; - - /// Creates an error message for the given exception. - /// Will try to reconstruct the original stack trace from the exception value, - /// or capture the current stack trace if not available. - pub fn CreateMessage( - isolate: &Isolate, - mut exception: Local, - ) -> Local { - unsafe { - Local::from_raw(v8__Exception__CreateMessage(isolate, &mut *exception)) - } - .unwrap() - } - - /// Returns the original stack trace that was captured at the creation time - /// of a given exception, or an empty handle if not available. - pub fn GetStackTrace( - mut exception: Local, - ) -> Option> { - unsafe { Local::from_raw(v8__Exception__GetStackTrace(&mut *exception)) } - } - - pub fn RangeError(mut message: Local) -> Local { - unsafe { Local::from_raw(v8__Exception__RangeError(&mut *message)) } - .unwrap() - } - - pub fn ReferenceError(mut message: Local) -> Local { - unsafe { Local::from_raw(v8__Exception__ReferenceError(&mut *message)) } - .unwrap() - } - - pub fn SyntaxError(mut message: Local) -> Local { - unsafe { Local::from_raw(v8__Exception__SyntaxError(&mut *message)) } - .unwrap() - } - - pub fn TypeError(mut message: Local) -> Local { - unsafe { Local::from_raw(v8__Exception__TypeError(&mut *message)) }.unwrap() - } - - pub fn Error(mut message: Local) -> Local { - unsafe { Local::from_raw(v8__Exception__Error(&mut *message)) }.unwrap() +/// Creates an error message for the given exception. +/// Will try to reconstruct the original stack trace from the exception value, +/// or capture the current stack trace if not available. +pub fn create_message( + isolate: &Isolate, + mut exception: Local, +) -> Local { + unsafe { + Local::from_raw(v8__Exception__CreateMessage(isolate, &mut *exception)) } + .unwrap() +} + +/// Returns the original stack trace that was captured at the creation time +/// of a given exception, or an empty handle if not available. +pub fn get_stack_trace( + mut exception: Local, +) -> Option> { + unsafe { Local::from_raw(v8__Exception__GetStackTrace(&mut *exception)) } +} + +pub fn range_error(mut message: Local) -> Local { + unsafe { Local::from_raw(v8__Exception__RangeError(&mut *message)) }.unwrap() +} + +pub fn reference_error(mut message: Local) -> Local { + unsafe { Local::from_raw(v8__Exception__ReferenceError(&mut *message)) } + .unwrap() +} + +pub fn syntax_error(mut message: Local) -> Local { + unsafe { Local::from_raw(v8__Exception__SyntaxError(&mut *message)) }.unwrap() +} + +pub fn type_error(mut message: Local) -> Local { + unsafe { Local::from_raw(v8__Exception__TypeError(&mut *message)) }.unwrap() +} + +pub fn error(mut message: Local) -> Local { + unsafe { Local::from_raw(v8__Exception__Error(&mut *message)) }.unwrap() } diff --git a/src/isolate.rs b/src/isolate.rs index f8b5c875..5bc82265 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -1,15 +1,15 @@ -use std::ops::Deref; -use std::ops::DerefMut; -use std::ptr::NonNull; - +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. use crate::array_buffer::Allocator; -use crate::exception::Message; use crate::promise::PromiseRejectMessage; use crate::support::Delete; use crate::support::Opaque; use crate::support::UniqueRef; use crate::Local; +use crate::Message; use crate::Value; +use std::ops::Deref; +use std::ops::DerefMut; +use std::ptr::NonNull; type MessageCallback = extern "C" fn(Local, Local); @@ -44,6 +44,12 @@ extern "C" { } #[repr(C)] +/// Isolate represents an isolated instance of the V8 engine. V8 isolates have +/// completely separate states. Objects from one isolate must not be used in +/// other 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. pub struct Isolate(Opaque); impl Isolate { diff --git a/src/json.rs b/src/json.rs index 2e73ef5d..52a12501 100644 --- a/src/json.rs +++ b/src/json.rs @@ -1,5 +1,5 @@ -#![allow(non_snake_case)] - +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +//! A JSON Parser and Stringifier. use crate::Context; use crate::Local; use crate::String; @@ -16,29 +16,22 @@ extern "C" { ) -> *mut String; } -/// A JSON Parser and Stringifier -pub mod JSON { - use super::*; +/// Tries to parse the string `json_string` and returns it as value if +/// successful. +pub fn parse( + mut context: Local, + mut json_string: Local, +) -> Option> { + unsafe { Local::from_raw(v8__JSON__Parse(&mut *context, &mut *json_string)) } +} - /// Tries to parse the string `json_string` and returns it as value if - /// successful. - pub fn Parse( - mut context: Local, - mut json_string: Local, - ) -> Option> { - unsafe { - Local::from_raw(v8__JSON__Parse(&mut *context, &mut *json_string)) - } - } - - /// Tries to stringify the JSON-serializable object `json_object` and returns - /// it as string if successful. - pub fn Stringify( - mut context: Local, - mut json_object: Local, - ) -> Option> { - unsafe { - Local::from_raw(v8__JSON__Stringify(&mut *context, &mut *json_object)) - } +/// Tries to stringify the JSON-serializable object `json_object` and returns +/// it as string if successful. +pub fn stringify( + mut context: Local, + mut json_object: Local, +) -> Option> { + unsafe { + Local::from_raw(v8__JSON__Stringify(&mut *context, &mut *json_object)) } } diff --git a/src/lib.rs b/src/lib.rs index ced244c5..9dbd62af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,6 @@ mod exception; mod function; mod handle_scope; mod isolate; -mod json; mod local; mod locker; mod number; @@ -28,6 +27,7 @@ mod value; pub mod array_buffer; pub mod inspector; +pub mod json; pub mod platform; // This module is intentionally named "V8" rather than "v8" to match the // C++ namespace "v8::V8". @@ -35,13 +35,11 @@ pub mod platform; pub mod V8; pub use context::Context; -pub use exception::Exception; -pub use exception::Message; +pub use exception::*; pub use function::{Function, FunctionCallbackInfo, FunctionTemplate}; pub use handle_scope::HandleScope; pub use isolate::Isolate; pub use isolate::OwnedIsolate; -pub use json::JSON; pub use local::Local; pub use locker::Locker; pub use number::{Integer, Number}; diff --git a/src/locker.rs b/src/locker.rs index aaeebb72..4d788355 100644 --- a/src/locker.rs +++ b/src/locker.rs @@ -1,14 +1,6 @@ -use std::mem::MaybeUninit; - +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. use crate::isolate::Isolate; - -// class Locker { -// public: -// explicit Locker(Isolate* isolate); -// ~Locker(); -// static bool IsLocked(Isolate* isolate); -// static bool IsActive(); -// } +use std::mem::MaybeUninit; extern "C" { fn v8__Locker__CONSTRUCT(buf: &mut MaybeUninit, isolate: &Isolate); @@ -16,9 +8,14 @@ extern "C" { } #[repr(C)] +/// v8::Locker is a scoped lock object. While it's active, i.e. between its +/// construction and destruction, the current thread is allowed to use the locked +/// isolate. V8 guarantees that an isolate can be locked by at most one thread at +/// any time. In other words, the scope of a v8::Locker is a critical section. pub struct Locker([usize; 2]); impl Locker { + /// Initialize Locker for a given Isolate. pub fn new(isolate: &Isolate) -> Self { let mut buf = MaybeUninit::::uninit(); unsafe { diff --git a/tests/test_api.rs b/tests/test_api.rs index bbcbd9ec..34d3a109 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -307,19 +307,19 @@ fn exception() { context.enter(); let reference = "This is a test error"; let local = v8_str(&isolate, reference); - v8::Exception::RangeError(local); - v8::Exception::ReferenceError(local); - v8::Exception::SyntaxError(local); - v8::Exception::TypeError(local); - let exception = v8::Exception::Error(local); - let msg = v8::Exception::CreateMessage(&isolate, exception); + v8::range_error(local); + v8::reference_error(local); + v8::syntax_error(local); + v8::type_error(local); + let exception = v8::error(local); + let msg = v8::create_message(&isolate, exception); let msg_string = msg.get(); let rust_msg_string = msg_string.to_rust_string_lossy(&isolate); assert_eq!( "Uncaught Error: This is a test error".to_string(), rust_msg_string ); - assert!(v8::Exception::GetStackTrace(exception).is_none()); + assert!(v8::get_stack_trace(exception).is_none()); context.exit(); }); drop(locker); @@ -339,10 +339,10 @@ fn json() { let mut context = v8::Context::new(&isolate); context.enter(); let json_string = v8_str(&isolate, "{\"a\": 1, \"b\": 2}"); - let maybe_value = v8::JSON::Parse(context, json_string); + let maybe_value = v8::json::parse(context, json_string); assert!(maybe_value.is_some()); let value = maybe_value.unwrap(); - let maybe_stringified = v8::JSON::Stringify(context, value); + let maybe_stringified = v8::json::stringify(context, value); assert!(maybe_stringified.is_some()); let stringified = maybe_stringified.unwrap(); let rust_str = stringified.to_rust_string_lossy(&isolate);