├── v8-sys ├── lib │ └── README.md ├── src │ ├── wrapper.hpp │ ├── lib.rs │ ├── v8-version.h │ ├── libplatform │ │ ├── libplatform-export.h │ │ ├── libplatform.h │ │ └── v8-tracing.h │ ├── v8-version-string.h │ ├── v8-platform.h │ └── v8config.h ├── Cargo.toml └── build.rs ├── .gitignore ├── src ├── lib.rs ├── handle.rs ├── context.rs ├── main.rs └── isolate.rs ├── Cargo.toml ├── README.md └── LICENSE /v8-sys/lib/README.md: -------------------------------------------------------------------------------- 1 | You can place static libraries for linking here. -------------------------------------------------------------------------------- /v8-sys/src/wrapper.hpp: -------------------------------------------------------------------------------- 1 | #include "v8.h" 2 | #include "v8-platform.h" 3 | #include "libplatform/libplatform.h" -------------------------------------------------------------------------------- /v8-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_upper_case_globals)] 2 | #![allow(non_camel_case_types)] 3 | #![allow(non_snake_case)] 4 | 5 | include!(concat!(env!("OUT_DIR"), "/bindings.rs")); 6 | 7 | //#[doc(inline)] 8 | pub use self::root::__BindgenBitfieldUnit; 9 | pub use self::root::_iobuf; 10 | pub use self::root::std as cppstd; 11 | pub use self::root::v8; 12 | pub use self::root::FILE; 13 | // #[doc(inline)] 14 | // pub use self::root::*; 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | v8-sys/lib/*.lib 13 | v8-sys/target/* 14 | v8-sys/Cargo.lock 15 | natives_blob.bin 16 | snapshot_blob.bin -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A high-level wrapper around the [V8 Javascript engine][1]. 2 | //! 3 | //! 4 | //! [1]: https://developers.google.com/v8/ 5 | 6 | #[macro_use()] 7 | extern crate lazy_static; 8 | 9 | pub mod context; 10 | // pub mod error; 11 | pub mod handle; 12 | pub mod isolate; 13 | //pub mod script; 14 | // pub mod template; 15 | // pub mod value; 16 | 17 | pub use self::context::Context; 18 | pub use self::isolate::Isolate; 19 | //pub use script::Script; 20 | //pub use value::Value; 21 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | cargo-features = ["edition"] 2 | [package] 3 | name = "v8" 4 | authors = ["David Flemström ", "Dickson Tan "] 5 | description = "High-level bindings to V8, the Javascript engine" 6 | keywords = ["v8", "javascript", "js", "ecmascript", "google",] 7 | license = "Apache-2.0" 8 | repository = "https://github.com/neurrone/v8-rs" 9 | edition = '2018' 10 | version = "0.1.0" 11 | 12 | [dependencies] 13 | lazy_static = "1.1.0" 14 | v8-sys = {path = "v8-sys", version = "0.1.0" } 15 | 16 | [features] 17 | bindgen = ["v8-sys/bindgen"] 18 | 19 | [workspace] 20 | members = ["v8-sys"] 21 | -------------------------------------------------------------------------------- /v8-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | cargo-features = ["edition"] 2 | [package] 3 | name = "v8-sys" 4 | authors = ["David Flemström ", "Dickson Tan "] 5 | description = "Low-level bindings to V8, the Javascript engine" 6 | build = "build.rs" 7 | edition = '2018' 8 | keywords = ["v8", "javascript", "js", "ecmascript", "google"] 9 | license = "Apache-2.0" 10 | repository = "https://github.com/neurrone/v8-rs/tree/master/v8-sys" 11 | version = "0.1.0" 12 | 13 | [lib] 14 | name = "v8_sys" 15 | crate-type = ["lib"] 16 | 17 | [dependencies] 18 | 19 | [build-dependencies] 20 | #cc = "1.0.23" 21 | 22 | [build-dependencies.bindgen] 23 | version = "0.39.0" 24 | optional = true 25 | 26 | [features] 27 | default = [] 28 | use-bindgen = ["bindgen"] -------------------------------------------------------------------------------- /v8-sys/src/v8-version.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_INCLUDE_VERSION_H_ // V8_VERSION_H_ conflicts with src/version.h 6 | #define V8_INCLUDE_VERSION_H_ 7 | 8 | // These macros define the version number for the current version. 9 | // NOTE these macros are used by some of the tool scripts and the build 10 | // system so their names cannot be changed without changing the scripts. 11 | #define V8_MAJOR_VERSION 7 12 | #define V8_MINOR_VERSION 1 13 | #define V8_BUILD_NUMBER 0 14 | #define V8_PATCH_LEVEL 0 15 | 16 | // Use 1 for candidates and 0 otherwise. 17 | // (Boolean macro values are not supported by all preprocessors.) 18 | #define V8_IS_CANDIDATE_VERSION 1 19 | 20 | #endif // V8_INCLUDE_VERSION_H_ 21 | -------------------------------------------------------------------------------- /v8-sys/src/libplatform/libplatform-export.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ 6 | #define V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ 7 | 8 | #if defined(_WIN32) 9 | 10 | #ifdef BUILDING_V8_PLATFORM_SHARED 11 | #define V8_PLATFORM_EXPORT __declspec(dllexport) 12 | #elif USING_V8_PLATFORM_SHARED 13 | #define V8_PLATFORM_EXPORT __declspec(dllimport) 14 | #else 15 | #define V8_PLATFORM_EXPORT 16 | #endif // BUILDING_V8_PLATFORM_SHARED 17 | 18 | #else // defined(_WIN32) 19 | 20 | // Setup for Linux shared library export. 21 | #ifdef BUILDING_V8_PLATFORM_SHARED 22 | #define V8_PLATFORM_EXPORT __attribute__((visibility("default"))) 23 | #else 24 | #define V8_PLATFORM_EXPORT 25 | #endif 26 | 27 | #endif // defined(_WIN32) 28 | 29 | #endif // V8_LIBPLATFORM_LIBPLATFORM_EXPORT_H_ 30 | -------------------------------------------------------------------------------- /v8-sys/src/v8-version-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_VERSION_STRING_H_ 6 | #define V8_VERSION_STRING_H_ 7 | 8 | #include "v8-version.h" // NOLINT(build/include) 9 | 10 | // This is here rather than v8-version.h to keep that file simple and 11 | // machine-processable. 12 | 13 | #if V8_IS_CANDIDATE_VERSION 14 | #define V8_CANDIDATE_STRING " (candidate)" 15 | #else 16 | #define V8_CANDIDATE_STRING "" 17 | #endif 18 | 19 | #ifndef V8_EMBEDDER_STRING 20 | #define V8_EMBEDDER_STRING "" 21 | #endif 22 | 23 | #define V8_SX(x) #x 24 | #define V8_S(x) V8_SX(x) 25 | 26 | #if V8_PATCH_LEVEL > 0 27 | #define V8_VERSION_STRING \ 28 | V8_S(V8_MAJOR_VERSION) \ 29 | "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) "." V8_S( \ 30 | V8_PATCH_LEVEL) V8_EMBEDDER_STRING V8_CANDIDATE_STRING 31 | #else 32 | #define V8_VERSION_STRING \ 33 | V8_S(V8_MAJOR_VERSION) \ 34 | "." V8_S(V8_MINOR_VERSION) "." V8_S(V8_BUILD_NUMBER) \ 35 | V8_EMBEDDER_STRING V8_CANDIDATE_STRING 36 | #endif 37 | 38 | #endif // V8_VERSION_STRING_H_ 39 | -------------------------------------------------------------------------------- /src/handle.rs: -------------------------------------------------------------------------------- 1 | use super::isolate; 2 | use std::convert; 3 | use std::marker; 4 | use std::mem; 5 | use std::ops; 6 | use std::ptr; 7 | use v8_sys::v8; 8 | 9 | #[derive(Debug)] 10 | pub struct Scope<'i>( 11 | pub v8::HandleScope, 12 | pub marker::PhantomData<&'i isolate::Isolate>, 13 | ); 14 | 15 | #[derive(Debug, Copy, Clone)] 16 | pub struct Local<'i, 's, A>(v8::Local, marker::PhantomData<&'s Scope<'i>>) 17 | where 18 | 'i: 's; 19 | 20 | #[derive(Debug, Copy, Clone)] 21 | pub struct MaybeLocal<'i, 's, A>(v8::MaybeLocal, marker::PhantomData<&'s Scope<'i>>) 22 | where 23 | 'i: 's; 24 | 25 | /* 26 | #[derive(Debug, Copy, Clone)] 27 | pub struct Eternal<'i, A>(v8::Eternal, marker::PhantomData<&'i isolate::Isolate>); 28 | */ 29 | 30 | #[derive(Debug)] 31 | pub struct Persistent<'i, A>(v8::Persistent, marker::PhantomData<&'i isolate::Isolate>); 32 | 33 | impl<'i, 's, A> Local<'i, 's, A> { 34 | pub unsafe fn new(value: v8::Local) -> Local<'i, 's, A> { 35 | assert_eq!(mem::size_of::(), mem::size_of::()); 36 | Local(mem::transmute(value), marker::PhantomData) 37 | } 38 | 39 | pub fn into_raw(self) -> v8::Local { 40 | self.0 41 | } 42 | } 43 | 44 | impl<'i, 's, A> convert::From> for Local<'i, 's, A> { 45 | fn from(other: v8::Local) -> Self { 46 | Local(other, marker::PhantomData) 47 | } 48 | } 49 | 50 | impl<'i, 's, A> ops::Deref for Local<'i, 's, A> { 51 | type Target = A; 52 | 53 | fn deref(&self) -> &Self::Target { 54 | unsafe { self.0.val_.as_ref() }.unwrap() 55 | } 56 | } 57 | 58 | impl<'i, 's, A> ops::DerefMut for Local<'i, 's, A> { 59 | fn deref_mut(&mut self) -> &mut Self::Target { 60 | unsafe { self.0.val_.as_mut() }.unwrap() 61 | } 62 | } 63 | 64 | impl<'i, 's, A> MaybeLocal<'i, 's, A> { 65 | pub fn empty() -> MaybeLocal<'i, 's, A> { 66 | MaybeLocal( 67 | v8::MaybeLocal { 68 | val_: ptr::null_mut(), 69 | _phantom_0: marker::PhantomData, 70 | }, 71 | marker::PhantomData, 72 | ) 73 | } 74 | 75 | pub fn into_raw(self) -> v8::MaybeLocal { 76 | self.0 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/context.rs: -------------------------------------------------------------------------------- 1 | //! Execution contexts and sandboxing. 2 | use super::{handle, isolate}; 3 | use std::ptr; 4 | use v8_sys::v8; 5 | // use value; 6 | 7 | /// A sandboxed execution context with its own set of built-in objects and functions. 8 | #[derive(Debug)] 9 | pub struct Context(v8::Context); 10 | 11 | /// A guard that keeps a context bound while it is in scope. 12 | #[must_use] 13 | pub struct Scope<'c>(&'c mut Context); 14 | 15 | impl Context { 16 | /// Creates a new context and returns a handle to the newly allocated context. 17 | pub fn new<'i, 's>( 18 | // _scope: &'s handle::Scope, 19 | isolate: &'i isolate::Isolate 20 | ) -> handle::Local<'i, 's, Context> { 21 | unsafe { 22 | println!("in context::new()"); 23 | let cb = v8::DeserializeInternalFieldsCallback { 24 | callback: None, 25 | data: ptr::null_mut(), 26 | }; 27 | println!("callback created"); 28 | let h = handle::MaybeLocal::empty().into_raw(); 29 | let i = handle::MaybeLocal::empty().into_raw(); 30 | let c = v8::Context::New(isolate.as_ptr(), ptr::null_mut(), h, i, cb); 31 | println!("About to return local handle"); 32 | handle::Local::new(c) 33 | } 34 | } 35 | 36 | /// Binds the context to the current scope. 37 | /// 38 | /// Within this scope, functionality that relies on implicit contexts will work. 39 | pub fn scope(&mut self) -> Scope { 40 | unsafe { 41 | self.0.Enter(); 42 | } 43 | Scope(self) 44 | } 45 | 46 | /* 47 | /// Returns the global proxy object. 48 | /// 49 | /// Global proxy object is a thin wrapper whose prototype points to actual context's global 50 | /// object with the properties like Object, etc. This is done that way for security reasons (for 51 | /// more details see https://wiki.mozilla.org/Gecko:SplitWindow). 52 | /// 53 | /// Please note that changes to global proxy object prototype most probably would break VM---v8 54 | /// expects only global object as a prototype of global proxy object. 55 | /// 56 | pub fn global(&self) -> handle::Local { 57 | unsafe { 58 | handle::Local::new(self.0.Global()) 59 | } 60 | } 61 | */ 62 | } 63 | 64 | impl<'c> Scope<'c> { 65 | pub fn context(&self) -> &Context { 66 | &self.0 67 | } 68 | 69 | pub fn context_mut(&mut self) -> &mut Context { 70 | &mut self.0 71 | } 72 | } 73 | 74 | impl<'c> Drop for Scope<'c> { 75 | fn drop(&mut self) { 76 | unsafe { (self.0).0.Exit() } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # V8-rs: An idiomatic Rust wrapper for the V8 Javascript engine 2 | 3 | Rust bindings for [v8][v8] 7.0, the JavaScript engine. 4 | 5 | This is an attempt to rewrite the existing [v8 crate](https://github.com/dflemstr/v8-rs) to enable it to work with the latest version of V8. Hence, substantial portions of its code were used whenever possible. 6 | 7 | ## Documentation 8 | 9 | Use `cargo doc --open`. This is not on crates.io yet, since this is highly experimental, and an existing crate already exists with this name. 10 | 11 | ## Requirements 12 | 13 | * Llatest nightly Rust. 14 | * Static libraries for V8 built with snapshot support and without i18n support for now, see [V8's official build instructions](https://github.com/v8/v8/wiki/Building-from-Source). V8-sys will look for the necessary .libs to link against in the `V8_LIBS` environment variable if defined, or v8-sys's `CARGO_MANIFEST_DIR/lib` folder otherwise. 15 | * Place `natives_blob.bin` and `snapshot_blob.bin` next to executables (currently only `main.rs`) using this crate. 16 | 17 | ## Installation 18 | 19 | Clone from GitHub to obtain the latest development version, ensure you have V8 static libraries, then `cargo build`. 20 | 21 | ## Hints for building V8 statically on Windows 22 | 23 | Building on Windows is very frustrating due to some [known bugs](https://bugs.chromium.org/p/v8/issues/detail?id=8119). Here's how to get a successful build. 24 | 25 | 1. Follow the steps in the official documentation to check out the V8 repository and set up depot tools and other dependencies. The latest version of VS2017 works as well. 26 | 27 | 2. Edit the `args.gn` file in the `out.gn/x64-release` folder so it contains the following: 28 | 29 | ```sh 30 | is_debug = false 31 | target_cpu = "x64" 32 | is_component_build = false 33 | v8_static_library = true 34 | v8_enable_i18n_support=false 35 | is_clang=false 36 | use_lld = false 37 | ``` 38 | 39 | 3. Build the libraries for embedding with the following command: 40 | 41 | ```sh 42 | ninja -C out.gn/x64.release v8 43 | ``` 44 | 45 | The official documentation suggests using the `ninja -C out.gn/x64.release`, which builds tests and fuzzers in addition to the libraries. Besides taking twice as long, the build fails due to unfixed bugs in the compilation of tests. 46 | 47 | 4. You will need to place the following libraries from the build somewhere v8-sys can link against: `inspector.lib, v8_base_0.lib, v8_base_1.lib, v8_external_snapshot.lib, v8_init.lib, v8_initializers.lib, v8_libbase.lib, v8_libplatform.lib` and `v8_libsampler.lib`. 48 | 49 | Also see [How to build V8 on Windows and not go mad](https://medium.com/dailyjs/how-to-build-v8-on-windows-and-not-go-mad-6347c69aacd4). 50 | 51 | ## Generating the v8-sys bindings with bindgen 52 | 53 | The optional feature "use-bindgen" generates the low level bindings using the included V8 headers (version 7.0), which requires [bindgen](https://github.com/rust-lang-nursery/rust-bindgen) to be installed. Generating this shouldn't be necessary in most cases, as the bindings have already been bundled with this crate. 54 | 55 | [crates]: https://crates.io/ 56 | [v8]: https://developers.google.com/v8/ -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::marker; 2 | use std::{ffi::CString, ptr}; 3 | use v8_sys::{v8, v8::platform}; 4 | // use v8; 5 | 6 | fn main() { 7 | unsafe { 8 | let startup_data_dir = CString::new("./").unwrap(); 9 | v8::V8_InitializeExternalStartupData(startup_data_dir.as_ptr()); 10 | let p: *mut v8::TracingController = ptr::null_mut(); 11 | let platform = platform::CreateDefaultPlatform( 12 | 0, 13 | platform::IdleTaskSupport_kDisabled, 14 | platform::InProcessStackDumping_kDisabled, 15 | p, 16 | ); 17 | v8::V8_InitializePlatform(platform); 18 | v8::V8_Initialize(); 19 | println!("Initialized"); 20 | 21 | let params = v8::Isolate_CreateParams { 22 | entry_hook: None, 23 | code_event_handler: None, 24 | constraints: v8::ResourceConstraints { 25 | max_semi_space_size_in_kb_: 0, 26 | max_old_space_size_: 0, 27 | max_executable_size_: 0, 28 | stack_limit_: ptr::null_mut(), 29 | code_range_size_: 0, 30 | max_zone_pool_size_: 0, 31 | }, 32 | snapshot_blob: ptr::null_mut(), 33 | counter_lookup_callback: None, 34 | create_histogram_callback: None, 35 | add_histogram_sample_callback: None, 36 | external_references: ptr::null_mut(), 37 | only_terminate_in_safe_scope: false, 38 | allow_atomics_wait: true, 39 | array_buffer_allocator: v8::ArrayBuffer_Allocator::NewDefaultAllocator(), 40 | }; 41 | let mut isolate = 42 | ptr::NonNull::new(v8::Isolate::New(¶ms)).expect("Could not create Isolate"); 43 | isolate.as_mut().Enter(); 44 | 45 | println!("isolate created"); 46 | let hs = v8_sys::v8::HandleScope::new(isolate.as_ptr()); 47 | 48 | // Create a new context of execution 49 | // context creation currently crashes the application for some reason. 50 | let cb = v8::DeserializeInternalFieldsCallback { 51 | callback: None, 52 | data: ptr::null_mut(), 53 | }; 54 | let h = ::v8::handle::MaybeLocal::empty().into_raw(); 55 | let i = ::v8::handle::MaybeLocal::empty().into_raw(); 56 | println!("Just before calling Context constructor in V8, crashes after this."); 57 | let c = v8::Context::New(isolate.as_ptr(), ptr::null_mut(), h, i, cb); 58 | // let context = v8::Context::new(&isolate); 59 | println!("Created context"); 60 | /* 61 | // Load the source code that we want to evaluate 62 | // let source = value::String::from_str(&isolate, "'Hello, ' + 'World!'"); 63 | // Compile the source code. `unwrap()` panics if the code is invalid, 64 | // e.g. if there is a syntax error. 65 | // let script = v8::Script::compile(&isolate, &context, &source).unwrap(); 66 | // Run the compiled script. `unwrap()` panics if the code threw an 67 | // exception. 68 | // let result = script.run(&context).unwrap(); 69 | // Convert the result to a value::String. 70 | // let result_str = result.to_string(&context); 71 | */ 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /v8-sys/src/libplatform/libplatform.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_LIBPLATFORM_H_ 6 | #define V8_LIBPLATFORM_LIBPLATFORM_H_ 7 | 8 | #include "libplatform/libplatform-export.h" 9 | #include "libplatform/v8-tracing.h" 10 | #include "v8-platform.h" // NOLINT(build/include) 11 | #include "v8config.h" // NOLINT(build/include) 12 | 13 | namespace v8 { 14 | namespace platform { 15 | 16 | enum class IdleTaskSupport { kDisabled, kEnabled }; 17 | enum class InProcessStackDumping { kDisabled, kEnabled }; 18 | 19 | enum class MessageLoopBehavior : bool { 20 | kDoNotWait = false, 21 | kWaitForWork = true 22 | }; 23 | 24 | /** 25 | * Returns a new instance of the default v8::Platform implementation. 26 | * 27 | * The caller will take ownership of the returned pointer. |thread_pool_size| 28 | * is the number of worker threads to allocate for background jobs. If a value 29 | * of zero is passed, a suitable default based on the current number of 30 | * processors online will be chosen. 31 | * If |idle_task_support| is enabled then the platform will accept idle 32 | * tasks (IdleTasksEnabled will return true) and will rely on the embedder 33 | * calling v8::platform::RunIdleTasks to process the idle tasks. 34 | * If |tracing_controller| is nullptr, the default platform will create a 35 | * v8::platform::TracingController instance and use it. 36 | */ 37 | V8_PLATFORM_EXPORT std::unique_ptr NewDefaultPlatform( 38 | int thread_pool_size = 0, 39 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, 40 | InProcessStackDumping in_process_stack_dumping = 41 | InProcessStackDumping::kDisabled, 42 | std::unique_ptr tracing_controller = {}); 43 | 44 | V8_PLATFORM_EXPORT V8_DEPRECATE_SOON( 45 | "Use NewDefaultPlatform instead", 46 | v8::Platform* CreateDefaultPlatform( 47 | int thread_pool_size = 0, 48 | IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled, 49 | InProcessStackDumping in_process_stack_dumping = 50 | InProcessStackDumping::kDisabled, 51 | v8::TracingController* tracing_controller = nullptr)); 52 | 53 | /** 54 | * Pumps the message loop for the given isolate. 55 | * 56 | * The caller has to make sure that this is called from the right thread. 57 | * Returns true if a task was executed, and false otherwise. Unless requested 58 | * through the |behavior| parameter, this call does not block if no task is 59 | * pending. The |platform| has to be created using |NewDefaultPlatform|. 60 | */ 61 | V8_PLATFORM_EXPORT bool PumpMessageLoop( 62 | v8::Platform* platform, v8::Isolate* isolate, 63 | MessageLoopBehavior behavior = MessageLoopBehavior::kDoNotWait); 64 | 65 | /** 66 | * Runs pending idle tasks for at most |idle_time_in_seconds| seconds. 67 | * 68 | * The caller has to make sure that this is called from the right thread. 69 | * This call does not block if no task is pending. The |platform| has to be 70 | * created using |NewDefaultPlatform|. 71 | */ 72 | V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform, 73 | v8::Isolate* isolate, 74 | double idle_time_in_seconds); 75 | 76 | /** 77 | * Attempts to set the tracing controller for the given platform. 78 | * 79 | * The |platform| has to be created using |NewDefaultPlatform|. 80 | * 81 | */ 82 | V8_PLATFORM_EXPORT V8_DEPRECATE_SOON( 83 | "Access the DefaultPlatform directly", 84 | void SetTracingController( 85 | v8::Platform* platform, 86 | v8::platform::tracing::TracingController* tracing_controller)); 87 | 88 | } // namespace platform 89 | } // namespace v8 90 | 91 | #endif // V8_LIBPLATFORM_LIBPLATFORM_H_ 92 | -------------------------------------------------------------------------------- /v8-sys/build.rs: -------------------------------------------------------------------------------- 1 | // use cc; 2 | // extern crate cc; 3 | #[cfg(feature = "bindgen")] 4 | extern crate bindgen; 5 | use std::path::PathBuf; 6 | use std::{env, fs}; 7 | 8 | fn main() { 9 | let v8_libs_dir = env::var("V8_LIBS").unwrap_or_else(|_| { 10 | PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()) 11 | .join("lib") 12 | .to_string_lossy() 13 | .to_string() 14 | }); 15 | let mut libs = vec![ 16 | "inspector", 17 | "v8_base_0", 18 | "v8_base_1", 19 | "v8_external_snapshot", 20 | "v8_init", 21 | "v8_initializers", 22 | "v8_libbase", 23 | "v8_libplatform", 24 | "v8_libsampler", 25 | ]; 26 | // let mut libs = vec!["inspector", "v8_base_0", "v8_base_1", "v8_init", "v8_initializers", "v8_libbase", "v8_libplatform", "v8_libsampler", "v8_nosnapshot", "libcmtd", "torque_base", "torque_generated_initializers"]; 27 | if cfg!(windows) { 28 | // V8 also requires these 29 | libs.push("dbghelp"); 30 | libs.push("shlwapi"); 31 | libs.push("winmm"); 32 | // temporarily link to the MSVC debug multithreaded CRT to debug context crashing 33 | libs.push("libcmtd"); 34 | } 35 | 36 | for l in &libs { 37 | println!("cargo:rustc-link-lib=dylib={}", l); 38 | } 39 | println!("cargo:rustc-link-search={}", v8_libs_dir); 40 | /* 41 | cc::Build::new() 42 | .cpp(true) 43 | .warnings(true) 44 | .include(v8_includes_dir) 45 | .file("src/allocator.cpp") 46 | .file("src/isolate.cpp") 47 | .file("src/platform.cpp") 48 | .compile("librust-v8-impls.a"); 49 | 50 | // println!("cargo:rustc-link-lib=dylib=librust-v8-impls.a"); 51 | */ 52 | 53 | #[cfg(feature = "bindgen")] 54 | { 55 | generate_bindings(); 56 | } 57 | 58 | #[cfg(not(feature = "bindgen"))] 59 | { 60 | copy_pregenerated_bindings(); 61 | } 62 | } 63 | 64 | #[cfg(feature = "bindgen")] 65 | fn generate_bindings() { 66 | use std::path; 67 | let bindings = bindgen::Builder::default() 68 | .generate_comments(true) 69 | .header("src/wrapper.hpp") 70 | .rust_target(bindgen::RustTarget::Nightly) 71 | .clang_arg("--std=c++14") 72 | // Because there are some layout problems with these 73 | .opaque_type("std::.*") 74 | .whitelist_type("std::unique_ptr\\") 75 | .whitelist_type("v8::.*") 76 | .whitelist_type("rust_v8_impls::.*") 77 | .whitelist_function("v8::.*") 78 | .whitelist_function("rust_v8_impls::.*") 79 | .whitelist_var("v8::.*") 80 | .whitelist_var("rust_v8_impls::.*") 81 | // Re-structure the modules a bit and hide the "root" module 82 | .raw_line("#[doc(hidden)]") 83 | // .generate_inline_functions(true) 84 | .enable_cxx_namespaces() 85 | .derive_debug(true) 86 | .derive_hash(true) 87 | .derive_eq(true) 88 | .derive_partialeq(true) 89 | .rustfmt_bindings(true) 90 | .generate() 91 | .expect("unable to generate v8 bindings"); 92 | 93 | let out_path = path::PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR env var not set")); 94 | bindings 95 | .write_to_file(out_path.join("bindings.rs")) 96 | .expect("unable to write bindings file"); 97 | 98 | let crate_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); 99 | fs::copy( 100 | out_path.join("bindings.rs"), 101 | crate_path.join("pregenerated_bindings.rs"), 102 | ).expect("Couldn't find generated bindings!"); 103 | } 104 | 105 | #[cfg(not(feature = "bindgen"))] 106 | fn copy_pregenerated_bindings() { 107 | let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); 108 | let crate_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); 109 | fs::copy( 110 | crate_path.join("pregenerated_bindings.rs"), 111 | out_path.join("bindings.rs"), 112 | ).expect("Couldn't find pregenerated bindings!"); 113 | } 114 | -------------------------------------------------------------------------------- /src/isolate.rs: -------------------------------------------------------------------------------- 1 | //! Heap and execution isolation. 2 | //! 3 | //! # Usage 4 | //! 5 | //! Construct a new isolate with default settings by doing `Isolate::new()`. 6 | //! 7 | 8 | use std::{ffi::CString, ptr, sync}; 9 | use v8_sys::{v8, v8::platform}; 10 | 11 | static INITIALIZE: sync::Once = sync::ONCE_INIT; 12 | 13 | /// Isolate represents an isolated instance of the V8 engine. 14 | /// 15 | /// V8 isolates have completely separate states. Objects from one isolate must not be used in other 16 | /// isolates. The embedder can create multiple isolates and use them in parallel in multiple 17 | /// threads. An isolate can be entered by at most one thread at any given time. The 18 | /// Locker/Unlocker API must be used to synchronize. 19 | pub struct Isolate(ptr::NonNull); 20 | 21 | #[must_use] 22 | pub struct Scope<'i>(&'i mut Isolate); 23 | 24 | impl Isolate { 25 | /// Creates a new isolate. 26 | pub fn new() -> Isolate { 27 | ensure_initialized(); 28 | let raw = unsafe { 29 | // let mut params: v8::Isolate_CreateParams = mem::zeroed(); 30 | let params = v8::Isolate_CreateParams { 31 | entry_hook: None, 32 | code_event_handler: None, 33 | constraints: v8::ResourceConstraints { 34 | max_semi_space_size_in_kb_: 0, 35 | max_old_space_size_: 0, 36 | max_executable_size_: 0, 37 | stack_limit_: ptr::null_mut(), 38 | code_range_size_: 0, 39 | max_zone_pool_size_: 0, 40 | }, 41 | snapshot_blob: ptr::null_mut(), 42 | counter_lookup_callback: None, 43 | create_histogram_callback: None, 44 | add_histogram_sample_callback: None, 45 | external_references: ptr::null_mut(), 46 | only_terminate_in_safe_scope: false, 47 | allow_atomics_wait: true, 48 | array_buffer_allocator: v8::ArrayBuffer_Allocator::NewDefaultAllocator(), 49 | }; 50 | ptr::NonNull::new(v8::Isolate::New(¶ms)).expect("Could not create Isolate") 51 | }; 52 | /* 53 | unsafe { 54 | raw.as_mut().SetCaptureStackTraceForUncaughtExceptions(true, 1024, v8::StackTrace_StackTraceOptions_kDetailed); 55 | } 56 | */ 57 | Isolate(raw) 58 | } 59 | 60 | pub fn scope(&mut self) -> Scope { 61 | unsafe { self.0.as_mut().Enter() }; 62 | Scope(self) 63 | } 64 | 65 | pub fn enter(&mut self) { 66 | unsafe { self.0.as_mut().Enter() }; 67 | } 68 | 69 | /// Returns the underlying raw pointer behind this isolate. 70 | pub fn as_ptr(&self) -> *mut v8::Isolate { 71 | self.0.as_ptr() 72 | } 73 | 74 | /* 75 | /// Returns the context bound to the current thread for this isolate. 76 | /// 77 | /// A context will be bound by for example `Context::make_current`, or while inside of a 78 | /// function callback. 79 | pub fn current_context(&self) -> Option { 80 | unsafe { 81 | let raw = self.isolate(self.as_raw()).as_mut(); 82 | raw.map(|r| context::Context::from_raw(self, r)) 83 | } 84 | } 85 | */ 86 | } 87 | 88 | /* 89 | impl fmt::Debug for Isolate { 90 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 91 | write!( 92 | f, 93 | "Isolate({:?}, {:?})", 94 | unsafe { self.0.as_ref() }, 95 | self.data() 96 | ) 97 | } 98 | } 99 | */ 100 | 101 | impl Drop for Isolate { 102 | fn drop(&mut self) { 103 | unsafe { 104 | self.0.as_mut().Dispose(); 105 | } 106 | } 107 | } 108 | 109 | impl<'i> Scope<'i> { 110 | pub fn isolate(&self) -> &Isolate { 111 | &self.0 112 | } 113 | 114 | pub fn isolate_mut(&mut self) -> &mut Isolate { 115 | &mut self.0 116 | } 117 | } 118 | 119 | impl<'i> Drop for Scope<'i> { 120 | fn drop(&mut self) { 121 | unsafe { (self.0).0.as_mut().Exit() } 122 | } 123 | } 124 | 125 | fn ensure_initialized() { 126 | INITIALIZE.call_once(|| { 127 | unsafe { 128 | // v8::V8_InitializeICUDefaultLocation(ptr::null()); 129 | // let startup_data_dir = CString::new("D:/documents/dev/enigma-deps/v8-rs/target/debug/").unwrap(); 130 | let startup_data_dir = CString::new("./").unwrap(); 131 | v8::V8_InitializeExternalStartupData(startup_data_dir.as_ptr()); 132 | let platform = platform::CreateDefaultPlatform( 133 | 0, 134 | platform::IdleTaskSupport_kDisabled, 135 | platform::InProcessStackDumping_kDisabled, 136 | ptr::null_mut(), 137 | ); 138 | v8::V8_InitializePlatform(platform); 139 | // TODO: implement some form of cleanup 140 | v8::V8_Initialize(); 141 | println!("Initialized"); 142 | } 143 | }); 144 | } 145 | -------------------------------------------------------------------------------- /v8-sys/src/libplatform/v8-tracing.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_LIBPLATFORM_V8_TRACING_H_ 6 | #define V8_LIBPLATFORM_V8_TRACING_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "libplatform/libplatform-export.h" 14 | #include "v8-platform.h" // NOLINT(build/include) 15 | 16 | namespace v8 { 17 | 18 | namespace base { 19 | class Mutex; 20 | } // namespace base 21 | 22 | namespace platform { 23 | namespace tracing { 24 | 25 | const int kTraceMaxNumArgs = 2; 26 | 27 | class V8_PLATFORM_EXPORT TraceObject { 28 | public: 29 | union ArgValue { 30 | bool as_bool; 31 | uint64_t as_uint; 32 | int64_t as_int; 33 | double as_double; 34 | const void* as_pointer; 35 | const char* as_string; 36 | }; 37 | 38 | TraceObject() {} 39 | ~TraceObject(); 40 | void Initialize( 41 | char phase, const uint8_t* category_enabled_flag, const char* name, 42 | const char* scope, uint64_t id, uint64_t bind_id, int num_args, 43 | const char** arg_names, const uint8_t* arg_types, 44 | const uint64_t* arg_values, 45 | std::unique_ptr* arg_convertables, 46 | unsigned int flags, int64_t timestamp, int64_t cpu_timestamp); 47 | void UpdateDuration(int64_t timestamp, int64_t cpu_timestamp); 48 | void InitializeForTesting( 49 | char phase, const uint8_t* category_enabled_flag, const char* name, 50 | const char* scope, uint64_t id, uint64_t bind_id, int num_args, 51 | const char** arg_names, const uint8_t* arg_types, 52 | const uint64_t* arg_values, 53 | std::unique_ptr* arg_convertables, 54 | unsigned int flags, int pid, int tid, int64_t ts, int64_t tts, 55 | uint64_t duration, uint64_t cpu_duration); 56 | 57 | int pid() const { return pid_; } 58 | int tid() const { return tid_; } 59 | char phase() const { return phase_; } 60 | const uint8_t* category_enabled_flag() const { 61 | return category_enabled_flag_; 62 | } 63 | const char* name() const { return name_; } 64 | const char* scope() const { return scope_; } 65 | uint64_t id() const { return id_; } 66 | uint64_t bind_id() const { return bind_id_; } 67 | int num_args() const { return num_args_; } 68 | const char** arg_names() { return arg_names_; } 69 | uint8_t* arg_types() { return arg_types_; } 70 | ArgValue* arg_values() { return arg_values_; } 71 | std::unique_ptr* arg_convertables() { 72 | return arg_convertables_; 73 | } 74 | unsigned int flags() const { return flags_; } 75 | int64_t ts() { return ts_; } 76 | int64_t tts() { return tts_; } 77 | uint64_t duration() { return duration_; } 78 | uint64_t cpu_duration() { return cpu_duration_; } 79 | 80 | private: 81 | int pid_; 82 | int tid_; 83 | char phase_; 84 | const char* name_; 85 | const char* scope_; 86 | const uint8_t* category_enabled_flag_; 87 | uint64_t id_; 88 | uint64_t bind_id_; 89 | int num_args_ = 0; 90 | const char* arg_names_[kTraceMaxNumArgs]; 91 | uint8_t arg_types_[kTraceMaxNumArgs]; 92 | ArgValue arg_values_[kTraceMaxNumArgs]; 93 | std::unique_ptr 94 | arg_convertables_[kTraceMaxNumArgs]; 95 | char* parameter_copy_storage_ = nullptr; 96 | unsigned int flags_; 97 | int64_t ts_; 98 | int64_t tts_; 99 | uint64_t duration_; 100 | uint64_t cpu_duration_; 101 | 102 | // Disallow copy and assign 103 | TraceObject(const TraceObject&) = delete; 104 | void operator=(const TraceObject&) = delete; 105 | }; 106 | 107 | class V8_PLATFORM_EXPORT TraceWriter { 108 | public: 109 | TraceWriter() {} 110 | virtual ~TraceWriter() {} 111 | virtual void AppendTraceEvent(TraceObject* trace_event) = 0; 112 | virtual void Flush() = 0; 113 | 114 | static TraceWriter* CreateJSONTraceWriter(std::ostream& stream); 115 | static TraceWriter* CreateJSONTraceWriter(std::ostream& stream, 116 | const std::string& tag); 117 | 118 | private: 119 | // Disallow copy and assign 120 | TraceWriter(const TraceWriter&) = delete; 121 | void operator=(const TraceWriter&) = delete; 122 | }; 123 | 124 | class V8_PLATFORM_EXPORT TraceBufferChunk { 125 | public: 126 | explicit TraceBufferChunk(uint32_t seq); 127 | 128 | void Reset(uint32_t new_seq); 129 | bool IsFull() const { return next_free_ == kChunkSize; } 130 | TraceObject* AddTraceEvent(size_t* event_index); 131 | TraceObject* GetEventAt(size_t index) { return &chunk_[index]; } 132 | 133 | uint32_t seq() const { return seq_; } 134 | size_t size() const { return next_free_; } 135 | 136 | static const size_t kChunkSize = 64; 137 | 138 | private: 139 | size_t next_free_ = 0; 140 | TraceObject chunk_[kChunkSize]; 141 | uint32_t seq_; 142 | 143 | // Disallow copy and assign 144 | TraceBufferChunk(const TraceBufferChunk&) = delete; 145 | void operator=(const TraceBufferChunk&) = delete; 146 | }; 147 | 148 | class V8_PLATFORM_EXPORT TraceBuffer { 149 | public: 150 | TraceBuffer() {} 151 | virtual ~TraceBuffer() {} 152 | 153 | virtual TraceObject* AddTraceEvent(uint64_t* handle) = 0; 154 | virtual TraceObject* GetEventByHandle(uint64_t handle) = 0; 155 | virtual bool Flush() = 0; 156 | 157 | static const size_t kRingBufferChunks = 1024; 158 | 159 | static TraceBuffer* CreateTraceBufferRingBuffer(size_t max_chunks, 160 | TraceWriter* trace_writer); 161 | 162 | private: 163 | // Disallow copy and assign 164 | TraceBuffer(const TraceBuffer&) = delete; 165 | void operator=(const TraceBuffer&) = delete; 166 | }; 167 | 168 | // Options determines how the trace buffer stores data. 169 | enum TraceRecordMode { 170 | // Record until the trace buffer is full. 171 | RECORD_UNTIL_FULL, 172 | 173 | // Record until the user ends the trace. The trace buffer is a fixed size 174 | // and we use it as a ring buffer during recording. 175 | RECORD_CONTINUOUSLY, 176 | 177 | // Record until the trace buffer is full, but with a huge buffer size. 178 | RECORD_AS_MUCH_AS_POSSIBLE, 179 | 180 | // Echo to console. Events are discarded. 181 | ECHO_TO_CONSOLE, 182 | }; 183 | 184 | class V8_PLATFORM_EXPORT TraceConfig { 185 | public: 186 | typedef std::vector StringList; 187 | 188 | static TraceConfig* CreateDefaultTraceConfig(); 189 | 190 | TraceConfig() : enable_systrace_(false), enable_argument_filter_(false) {} 191 | TraceRecordMode GetTraceRecordMode() const { return record_mode_; } 192 | bool IsSystraceEnabled() const { return enable_systrace_; } 193 | bool IsArgumentFilterEnabled() const { return enable_argument_filter_; } 194 | 195 | void SetTraceRecordMode(TraceRecordMode mode) { record_mode_ = mode; } 196 | void EnableSystrace() { enable_systrace_ = true; } 197 | void EnableArgumentFilter() { enable_argument_filter_ = true; } 198 | 199 | void AddIncludedCategory(const char* included_category); 200 | 201 | bool IsCategoryGroupEnabled(const char* category_group) const; 202 | 203 | private: 204 | TraceRecordMode record_mode_; 205 | bool enable_systrace_ : 1; 206 | bool enable_argument_filter_ : 1; 207 | StringList included_categories_; 208 | 209 | // Disallow copy and assign 210 | TraceConfig(const TraceConfig&) = delete; 211 | void operator=(const TraceConfig&) = delete; 212 | }; 213 | 214 | #if defined(_MSC_VER) 215 | #define V8_PLATFORM_NON_EXPORTED_BASE(code) \ 216 | __pragma(warning(suppress : 4275)) code 217 | #else 218 | #define V8_PLATFORM_NON_EXPORTED_BASE(code) code 219 | #endif // defined(_MSC_VER) 220 | 221 | class V8_PLATFORM_EXPORT TracingController 222 | : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) { 223 | public: 224 | enum Mode { DISABLED = 0, RECORDING_MODE }; 225 | 226 | // The pointer returned from GetCategoryGroupEnabledInternal() points to a 227 | // value with zero or more of the following bits. Used in this class only. 228 | // The TRACE_EVENT macros should only use the value as a bool. 229 | // These values must be in sync with macro values in TraceEvent.h in Blink. 230 | enum CategoryGroupEnabledFlags { 231 | // Category group enabled for the recording mode. 232 | ENABLED_FOR_RECORDING = 1 << 0, 233 | // Category group enabled by SetEventCallbackEnabled(). 234 | ENABLED_FOR_EVENT_CALLBACK = 1 << 2, 235 | // Category group enabled to export events to ETW. 236 | ENABLED_FOR_ETW_EXPORT = 1 << 3 237 | }; 238 | 239 | TracingController(); 240 | ~TracingController() override; 241 | void Initialize(TraceBuffer* trace_buffer); 242 | 243 | // v8::TracingController implementation. 244 | const uint8_t* GetCategoryGroupEnabled(const char* category_group) override; 245 | uint64_t AddTraceEvent( 246 | char phase, const uint8_t* category_enabled_flag, const char* name, 247 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, 248 | const char** arg_names, const uint8_t* arg_types, 249 | const uint64_t* arg_values, 250 | std::unique_ptr* arg_convertables, 251 | unsigned int flags) override; 252 | uint64_t AddTraceEventWithTimestamp( 253 | char phase, const uint8_t* category_enabled_flag, const char* name, 254 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, 255 | const char** arg_names, const uint8_t* arg_types, 256 | const uint64_t* arg_values, 257 | std::unique_ptr* arg_convertables, 258 | unsigned int flags, int64_t timestamp) override; 259 | void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, 260 | const char* name, uint64_t handle) override; 261 | void AddTraceStateObserver( 262 | v8::TracingController::TraceStateObserver* observer) override; 263 | void RemoveTraceStateObserver( 264 | v8::TracingController::TraceStateObserver* observer) override; 265 | 266 | void StartTracing(TraceConfig* trace_config); 267 | void StopTracing(); 268 | 269 | static const char* GetCategoryGroupName(const uint8_t* category_enabled_flag); 270 | 271 | protected: 272 | virtual int64_t CurrentTimestampMicroseconds(); 273 | virtual int64_t CurrentCpuTimestampMicroseconds(); 274 | 275 | private: 276 | const uint8_t* GetCategoryGroupEnabledInternal(const char* category_group); 277 | void UpdateCategoryGroupEnabledFlag(size_t category_index); 278 | void UpdateCategoryGroupEnabledFlags(); 279 | 280 | std::unique_ptr trace_buffer_; 281 | std::unique_ptr trace_config_; 282 | std::unique_ptr mutex_; 283 | std::unordered_set observers_; 284 | Mode mode_ = DISABLED; 285 | 286 | // Disallow copy and assign 287 | TracingController(const TracingController&) = delete; 288 | void operator=(const TracingController&) = delete; 289 | }; 290 | 291 | #undef V8_PLATFORM_NON_EXPORTED_BASE 292 | 293 | } // namespace tracing 294 | } // namespace platform 295 | } // namespace v8 296 | 297 | #endif // V8_LIBPLATFORM_V8_TRACING_H_ 298 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /v8-sys/src/v8-platform.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8_V8_PLATFORM_H_ 6 | #define V8_V8_PLATFORM_H_ 7 | 8 | #include 9 | #include 10 | #include // For abort. 11 | #include 12 | #include 13 | 14 | #include "v8config.h" // NOLINT(build/include) 15 | 16 | namespace v8 { 17 | 18 | class Isolate; 19 | 20 | /** 21 | * A Task represents a unit of work. 22 | */ 23 | class Task { 24 | public: 25 | virtual ~Task() = default; 26 | 27 | virtual void Run() = 0; 28 | }; 29 | 30 | /** 31 | * An IdleTask represents a unit of work to be performed in idle time. 32 | * The Run method is invoked with an argument that specifies the deadline in 33 | * seconds returned by MonotonicallyIncreasingTime(). 34 | * The idle task is expected to complete by this deadline. 35 | */ 36 | class IdleTask { 37 | public: 38 | virtual ~IdleTask() = default; 39 | virtual void Run(double deadline_in_seconds) = 0; 40 | }; 41 | 42 | /** 43 | * A TaskRunner allows scheduling of tasks. The TaskRunner may still be used to 44 | * post tasks after the isolate gets destructed, but these tasks may not get 45 | * executed anymore. All tasks posted to a given TaskRunner will be invoked in 46 | * sequence. Tasks can be posted from any thread. 47 | */ 48 | class TaskRunner { 49 | public: 50 | /** 51 | * Schedules a task to be invoked by this TaskRunner. The TaskRunner 52 | * implementation takes ownership of |task|. 53 | */ 54 | virtual void PostTask(std::unique_ptr task) = 0; 55 | 56 | /** 57 | * Schedules a task to be invoked by this TaskRunner. The task is scheduled 58 | * after the given number of seconds |delay_in_seconds|. The TaskRunner 59 | * implementation takes ownership of |task|. 60 | */ 61 | virtual void PostDelayedTask(std::unique_ptr task, 62 | double delay_in_seconds) = 0; 63 | 64 | /** 65 | * Schedules an idle task to be invoked by this TaskRunner. The task is 66 | * scheduled when the embedder is idle. Requires that 67 | * TaskRunner::SupportsIdleTasks(isolate) is true. Idle tasks may be reordered 68 | * relative to other task types and may be starved for an arbitrarily long 69 | * time if no idle time is available. The TaskRunner implementation takes 70 | * ownership of |task|. 71 | */ 72 | virtual void PostIdleTask(std::unique_ptr task) = 0; 73 | 74 | /** 75 | * Returns true if idle tasks are enabled for this TaskRunner. 76 | */ 77 | virtual bool IdleTasksEnabled() = 0; 78 | 79 | TaskRunner() = default; 80 | virtual ~TaskRunner() = default; 81 | 82 | private: 83 | TaskRunner(const TaskRunner&) = delete; 84 | TaskRunner& operator=(const TaskRunner&) = delete; 85 | }; 86 | 87 | /** 88 | * The interface represents complex arguments to trace events. 89 | */ 90 | class ConvertableToTraceFormat { 91 | public: 92 | virtual ~ConvertableToTraceFormat() = default; 93 | 94 | /** 95 | * Append the class info to the provided |out| string. The appended 96 | * data must be a valid JSON object. Strings must be properly quoted, and 97 | * escaped. There is no processing applied to the content after it is 98 | * appended. 99 | */ 100 | virtual void AppendAsTraceFormat(std::string* out) const = 0; 101 | }; 102 | 103 | /** 104 | * V8 Tracing controller. 105 | * 106 | * Can be implemented by an embedder to record trace events from V8. 107 | */ 108 | class TracingController { 109 | public: 110 | virtual ~TracingController() = default; 111 | 112 | /** 113 | * Called by TRACE_EVENT* macros, don't call this directly. 114 | * The name parameter is a category group for example: 115 | * TRACE_EVENT0("v8,parse", "V8.Parse") 116 | * The pointer returned points to a value with zero or more of the bits 117 | * defined in CategoryGroupEnabledFlags. 118 | **/ 119 | virtual const uint8_t* GetCategoryGroupEnabled(const char* name) { 120 | static uint8_t no = 0; 121 | return &no; 122 | } 123 | 124 | /** 125 | * Adds a trace event to the platform tracing system. These function calls are 126 | * usually the result of a TRACE_* macro from trace_event_common.h when 127 | * tracing and the category of the particular trace are enabled. It is not 128 | * advisable to call these functions on their own; they are really only meant 129 | * to be used by the trace macros. The returned handle can be used by 130 | * UpdateTraceEventDuration to update the duration of COMPLETE events. 131 | */ 132 | virtual uint64_t AddTraceEvent( 133 | char phase, const uint8_t* category_enabled_flag, const char* name, 134 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, 135 | const char** arg_names, const uint8_t* arg_types, 136 | const uint64_t* arg_values, 137 | std::unique_ptr* arg_convertables, 138 | unsigned int flags) { 139 | return 0; 140 | } 141 | virtual uint64_t AddTraceEventWithTimestamp( 142 | char phase, const uint8_t* category_enabled_flag, const char* name, 143 | const char* scope, uint64_t id, uint64_t bind_id, int32_t num_args, 144 | const char** arg_names, const uint8_t* arg_types, 145 | const uint64_t* arg_values, 146 | std::unique_ptr* arg_convertables, 147 | unsigned int flags, int64_t timestamp) { 148 | return 0; 149 | } 150 | 151 | /** 152 | * Sets the duration field of a COMPLETE trace event. It must be called with 153 | * the handle returned from AddTraceEvent(). 154 | **/ 155 | virtual void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, 156 | const char* name, uint64_t handle) {} 157 | 158 | class TraceStateObserver { 159 | public: 160 | virtual ~TraceStateObserver() = default; 161 | virtual void OnTraceEnabled() = 0; 162 | virtual void OnTraceDisabled() = 0; 163 | }; 164 | 165 | /** Adds tracing state change observer. */ 166 | virtual void AddTraceStateObserver(TraceStateObserver*) {} 167 | 168 | /** Removes tracing state change observer. */ 169 | virtual void RemoveTraceStateObserver(TraceStateObserver*) {} 170 | }; 171 | 172 | /** 173 | * A V8 memory page allocator. 174 | * 175 | * Can be implemented by an embedder to manage large host OS allocations. 176 | */ 177 | class PageAllocator { 178 | public: 179 | virtual ~PageAllocator() = default; 180 | 181 | /** 182 | * Gets the page granularity for AllocatePages and FreePages. Addresses and 183 | * lengths for those calls should be multiples of AllocatePageSize(). 184 | */ 185 | virtual size_t AllocatePageSize() = 0; 186 | 187 | /** 188 | * Gets the page granularity for SetPermissions and ReleasePages. Addresses 189 | * and lengths for those calls should be multiples of CommitPageSize(). 190 | */ 191 | virtual size_t CommitPageSize() = 0; 192 | 193 | /** 194 | * Sets the random seed so that GetRandomMmapAddr() will generate repeatable 195 | * sequences of random mmap addresses. 196 | */ 197 | virtual void SetRandomMmapSeed(int64_t seed) = 0; 198 | 199 | /** 200 | * Returns a randomized address, suitable for memory allocation under ASLR. 201 | * The address will be aligned to AllocatePageSize. 202 | */ 203 | virtual void* GetRandomMmapAddr() = 0; 204 | 205 | /** 206 | * Memory permissions. 207 | */ 208 | enum Permission { 209 | kNoAccess, 210 | kRead, 211 | kReadWrite, 212 | // TODO(hpayer): Remove this flag. Memory should never be rwx. 213 | kReadWriteExecute, 214 | kReadExecute 215 | }; 216 | 217 | /** 218 | * Allocates memory in range with the given alignment and permission. 219 | */ 220 | virtual void* AllocatePages(void* address, size_t length, size_t alignment, 221 | Permission permissions) = 0; 222 | 223 | /** 224 | * Frees memory in a range that was allocated by a call to AllocatePages. 225 | */ 226 | virtual bool FreePages(void* address, size_t length) = 0; 227 | 228 | /** 229 | * Releases memory in a range that was allocated by a call to AllocatePages. 230 | */ 231 | virtual bool ReleasePages(void* address, size_t length, 232 | size_t new_length) = 0; 233 | 234 | /** 235 | * Sets permissions on pages in an allocated range. 236 | */ 237 | virtual bool SetPermissions(void* address, size_t length, 238 | Permission permissions) = 0; 239 | }; 240 | 241 | /** 242 | * V8 Platform abstraction layer. 243 | * 244 | * The embedder has to provide an implementation of this interface before 245 | * initializing the rest of V8. 246 | */ 247 | class Platform { 248 | public: 249 | virtual ~Platform() = default; 250 | 251 | /** 252 | * Allows the embedder to manage memory page allocations. 253 | */ 254 | virtual PageAllocator* GetPageAllocator() { 255 | // TODO(bbudge) Make this abstract after all embedders implement this. 256 | return nullptr; 257 | } 258 | 259 | /** 260 | * Enables the embedder to respond in cases where V8 can't allocate large 261 | * blocks of memory. V8 retries the failed allocation once after calling this 262 | * method. On success, execution continues; otherwise V8 exits with a fatal 263 | * error. 264 | * Embedder overrides of this function must NOT call back into V8. 265 | */ 266 | virtual void OnCriticalMemoryPressure() { 267 | // TODO(bbudge) Remove this when embedders override the following method. 268 | // See crbug.com/634547. 269 | } 270 | 271 | /** 272 | * Enables the embedder to respond in cases where V8 can't allocate large 273 | * memory regions. The |length| parameter is the amount of memory needed. 274 | * Returns true if memory is now available. Returns false if no memory could 275 | * be made available. V8 will retry allocations until this method returns 276 | * false. 277 | * 278 | * Embedder overrides of this function must NOT call back into V8. 279 | */ 280 | virtual bool OnCriticalMemoryPressure(size_t length) { return false; } 281 | 282 | /** 283 | * Gets the number of worker threads used by 284 | * Call(BlockingTask)OnWorkerThread(). This can be used to estimate the number 285 | * of tasks a work package should be split into. A return value of 0 means 286 | * that there are no worker threads available. Note that a value of 0 won't 287 | * prohibit V8 from posting tasks using |CallOnWorkerThread|. 288 | */ 289 | virtual int NumberOfWorkerThreads() = 0; 290 | 291 | /** 292 | * Returns a TaskRunner which can be used to post a task on the foreground. 293 | * This function should only be called from a foreground thread. 294 | */ 295 | virtual std::shared_ptr GetForegroundTaskRunner( 296 | Isolate* isolate) = 0; 297 | 298 | /** 299 | * Schedules a task to be invoked on a worker thread. 300 | */ 301 | virtual void CallOnWorkerThread(std::unique_ptr task) = 0; 302 | 303 | /** 304 | * Schedules a task that blocks the main thread to be invoked with 305 | * high-priority on a worker thread. 306 | */ 307 | virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr task) { 308 | // Embedders may optionally override this to process these tasks in a high 309 | // priority pool. 310 | CallOnWorkerThread(std::move(task)); 311 | } 312 | 313 | /** 314 | * Schedules a task to be invoked on a worker thread after |delay_in_seconds| 315 | * expires. 316 | */ 317 | virtual void CallDelayedOnWorkerThread(std::unique_ptr task, 318 | double delay_in_seconds) = 0; 319 | 320 | /** 321 | * Schedules a task to be invoked on a foreground thread wrt a specific 322 | * |isolate|. Tasks posted for the same isolate should be execute in order of 323 | * scheduling. The definition of "foreground" is opaque to V8. 324 | */ 325 | virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0; 326 | 327 | /** 328 | * Schedules a task to be invoked on a foreground thread wrt a specific 329 | * |isolate| after the given number of seconds |delay_in_seconds|. 330 | * Tasks posted for the same isolate should be execute in order of 331 | * scheduling. The definition of "foreground" is opaque to V8. 332 | */ 333 | virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, 334 | double delay_in_seconds) = 0; 335 | 336 | /** 337 | * Schedules a task to be invoked on a foreground thread wrt a specific 338 | * |isolate| when the embedder is idle. 339 | * Requires that SupportsIdleTasks(isolate) is true. 340 | * Idle tasks may be reordered relative to other task types and may be 341 | * starved for an arbitrarily long time if no idle time is available. 342 | * The definition of "foreground" is opaque to V8. 343 | */ 344 | virtual void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) { 345 | // This must be overriden if |IdleTasksEnabled()|. 346 | abort(); 347 | } 348 | 349 | /** 350 | * Returns true if idle tasks are enabled for the given |isolate|. 351 | */ 352 | virtual bool IdleTasksEnabled(Isolate* isolate) { 353 | return false; 354 | } 355 | 356 | /** 357 | * Monotonically increasing time in seconds from an arbitrary fixed point in 358 | * the past. This function is expected to return at least 359 | * millisecond-precision values. For this reason, 360 | * it is recommended that the fixed point be no further in the past than 361 | * the epoch. 362 | **/ 363 | virtual double MonotonicallyIncreasingTime() = 0; 364 | 365 | /** 366 | * Current wall-clock time in milliseconds since epoch. 367 | * This function is expected to return at least millisecond-precision values. 368 | */ 369 | virtual double CurrentClockTimeMillis() = 0; 370 | 371 | typedef void (*StackTracePrinter)(); 372 | 373 | /** 374 | * Returns a function pointer that print a stack trace of the current stack 375 | * on invocation. Disables printing of the stack trace if nullptr. 376 | */ 377 | virtual StackTracePrinter GetStackTracePrinter() { return nullptr; } 378 | 379 | /** 380 | * Returns an instance of a v8::TracingController. This must be non-nullptr. 381 | */ 382 | virtual TracingController* GetTracingController() = 0; 383 | 384 | protected: 385 | /** 386 | * Default implementation of current wall-clock time in milliseconds 387 | * since epoch. Useful for implementing |CurrentClockTimeMillis| if 388 | * nothing special needed. 389 | */ 390 | static double SystemClockTimeMillis(); 391 | }; 392 | 393 | } // namespace v8 394 | 395 | #endif // V8_V8_PLATFORM_H_ 396 | -------------------------------------------------------------------------------- /v8-sys/src/v8config.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 the V8 project authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef V8CONFIG_H_ 6 | #define V8CONFIG_H_ 7 | 8 | // clang-format off 9 | 10 | // Platform headers for feature detection below. 11 | #if defined(__ANDROID__) 12 | # include 13 | #elif defined(__APPLE__) 14 | # include 15 | #elif defined(__linux__) 16 | # include 17 | #endif 18 | 19 | 20 | // This macro allows to test for the version of the GNU C library (or 21 | // a compatible C library that masquerades as glibc). It evaluates to 22 | // 0 if libc is not GNU libc or compatible. 23 | // Use like: 24 | // #if V8_GLIBC_PREREQ(2, 3) 25 | // ... 26 | // #endif 27 | #if defined(__GLIBC__) && defined(__GLIBC_MINOR__) 28 | # define V8_GLIBC_PREREQ(major, minor) \ 29 | ((__GLIBC__ * 100 + __GLIBC_MINOR__) >= ((major) * 100 + (minor))) 30 | #else 31 | # define V8_GLIBC_PREREQ(major, minor) 0 32 | #endif 33 | 34 | 35 | // This macro allows to test for the version of the GNU C++ compiler. 36 | // Note that this also applies to compilers that masquerade as GCC, 37 | // for example clang and the Intel C++ compiler for Linux. 38 | // Use like: 39 | // #if V8_GNUC_PREREQ(4, 3, 1) 40 | // ... 41 | // #endif 42 | #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) 43 | # define V8_GNUC_PREREQ(major, minor, patchlevel) \ 44 | ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \ 45 | ((major) * 10000 + (minor) * 100 + (patchlevel))) 46 | #elif defined(__GNUC__) && defined(__GNUC_MINOR__) 47 | # define V8_GNUC_PREREQ(major, minor, patchlevel) \ 48 | ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= \ 49 | ((major) * 10000 + (minor) * 100 + (patchlevel))) 50 | #else 51 | # define V8_GNUC_PREREQ(major, minor, patchlevel) 0 52 | #endif 53 | 54 | 55 | 56 | // ----------------------------------------------------------------------------- 57 | // Operating system detection 58 | // 59 | // V8_OS_ANDROID - Android 60 | // V8_OS_BSD - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD) 61 | // V8_OS_CYGWIN - Cygwin 62 | // V8_OS_DRAGONFLYBSD - DragonFlyBSD 63 | // V8_OS_FREEBSD - FreeBSD 64 | // V8_OS_FUCHSIA - Fuchsia 65 | // V8_OS_LINUX - Linux 66 | // V8_OS_MACOSX - Mac OS X 67 | // V8_OS_NETBSD - NetBSD 68 | // V8_OS_OPENBSD - OpenBSD 69 | // V8_OS_POSIX - POSIX compatible (mostly everything except Windows) 70 | // V8_OS_QNX - QNX Neutrino 71 | // V8_OS_SOLARIS - Sun Solaris and OpenSolaris 72 | // V8_OS_AIX - AIX 73 | // V8_OS_WIN - Microsoft Windows 74 | 75 | #if defined(__ANDROID__) 76 | # define V8_OS_ANDROID 1 77 | # define V8_OS_LINUX 1 78 | # define V8_OS_POSIX 1 79 | #elif defined(__APPLE__) 80 | # define V8_OS_BSD 1 81 | # define V8_OS_MACOSX 1 82 | # define V8_OS_POSIX 1 83 | #elif defined(__CYGWIN__) 84 | # define V8_OS_CYGWIN 1 85 | # define V8_OS_POSIX 1 86 | #elif defined(__linux__) 87 | # define V8_OS_LINUX 1 88 | # define V8_OS_POSIX 1 89 | #elif defined(__sun) 90 | # define V8_OS_POSIX 1 91 | # define V8_OS_SOLARIS 1 92 | #elif defined(_AIX) 93 | #define V8_OS_POSIX 1 94 | #define V8_OS_AIX 1 95 | #elif defined(__FreeBSD__) 96 | # define V8_OS_BSD 1 97 | # define V8_OS_FREEBSD 1 98 | # define V8_OS_POSIX 1 99 | #elif defined(__Fuchsia__) 100 | # define V8_OS_FUCHSIA 1 101 | # define V8_OS_POSIX 1 102 | #elif defined(__DragonFly__) 103 | # define V8_OS_BSD 1 104 | # define V8_OS_DRAGONFLYBSD 1 105 | # define V8_OS_POSIX 1 106 | #elif defined(__NetBSD__) 107 | # define V8_OS_BSD 1 108 | # define V8_OS_NETBSD 1 109 | # define V8_OS_POSIX 1 110 | #elif defined(__OpenBSD__) 111 | # define V8_OS_BSD 1 112 | # define V8_OS_OPENBSD 1 113 | # define V8_OS_POSIX 1 114 | #elif defined(__QNXNTO__) 115 | # define V8_OS_POSIX 1 116 | # define V8_OS_QNX 1 117 | #elif defined(_WIN32) 118 | # define V8_OS_WIN 1 119 | #endif 120 | 121 | 122 | // ----------------------------------------------------------------------------- 123 | // C library detection 124 | // 125 | // V8_LIBC_MSVCRT - MSVC libc 126 | // V8_LIBC_BIONIC - Bionic libc 127 | // V8_LIBC_BSD - BSD libc derivate 128 | // V8_LIBC_GLIBC - GNU C library 129 | // V8_LIBC_UCLIBC - uClibc 130 | // 131 | // Note that testing for libc must be done using #if not #ifdef. For example, 132 | // to test for the GNU C library, use: 133 | // #if V8_LIBC_GLIBC 134 | // ... 135 | // #endif 136 | 137 | #if defined (_MSC_VER) 138 | # define V8_LIBC_MSVCRT 1 139 | #elif defined(__BIONIC__) 140 | # define V8_LIBC_BIONIC 1 141 | # define V8_LIBC_BSD 1 142 | #elif defined(__UCLIBC__) 143 | // Must test for UCLIBC before GLIBC, as UCLIBC pretends to be GLIBC. 144 | # define V8_LIBC_UCLIBC 1 145 | #elif defined(__GLIBC__) || defined(__GNU_LIBRARY__) 146 | # define V8_LIBC_GLIBC 1 147 | #else 148 | # define V8_LIBC_BSD V8_OS_BSD 149 | #endif 150 | 151 | 152 | // ----------------------------------------------------------------------------- 153 | // Compiler detection 154 | // 155 | // V8_CC_GNU - GCC, or clang in gcc mode 156 | // V8_CC_INTEL - Intel C++ 157 | // V8_CC_MINGW - Minimalist GNU for Windows 158 | // V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32) 159 | // V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64) 160 | // V8_CC_MSVC - Microsoft Visual C/C++, or clang in cl.exe mode 161 | // 162 | // C++11 feature detection 163 | // 164 | // V8_HAS_CXX11_ALIGNAS - alignas specifier supported 165 | // V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported 166 | // 167 | // Compiler-specific feature detection 168 | // 169 | // V8_HAS___ALIGNOF - __alignof(type) operator supported 170 | // V8_HAS___ALIGNOF__ - __alignof__(type) operator supported 171 | // V8_HAS_ATTRIBUTE_ALIGNED - __attribute__((aligned(n))) supported 172 | // V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline)) 173 | // supported 174 | // V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported 175 | // V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported 176 | // V8_HAS_ATTRIBUTE_UNUSED - __attribute__((unused)) supported 177 | // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported 178 | // V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result)) 179 | // supported 180 | // V8_HAS_BUILTIN_BSWAP16 - __builtin_bswap16() supported 181 | // V8_HAS_BUILTIN_BSWAP32 - __builtin_bswap32() supported 182 | // V8_HAS_BUILTIN_BSWAP64 - __builtin_bswap64() supported 183 | // V8_HAS_BUILTIN_CLZ - __builtin_clz() supported 184 | // V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported 185 | // V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported 186 | // V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported 187 | // V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported 188 | // V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported 189 | // V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported 190 | // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported 191 | // V8_HAS_DECLSPEC_ALIGN - __declspec(align(n)) supported 192 | // V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported 193 | // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported 194 | // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported 195 | // V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported 196 | // V8_HAS___FORCEINLINE - __forceinline supported 197 | // 198 | // Note that testing for compilers and/or features must be done using #if 199 | // not #ifdef. For example, to test for Intel C++ Compiler, use: 200 | // #if V8_CC_INTEL 201 | // ... 202 | // #endif 203 | 204 | #if defined(__clang__) 205 | 206 | #if defined(__GNUC__) // Clang in gcc mode. 207 | # define V8_CC_GNU 1 208 | #endif 209 | 210 | // Clang defines __alignof__ as alias for __alignof 211 | # define V8_HAS___ALIGNOF 1 212 | # define V8_HAS___ALIGNOF__ V8_HAS___ALIGNOF 213 | 214 | # define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned)) 215 | # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) 216 | # define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated)) 217 | # define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE \ 218 | (__has_extension(attribute_deprecated_with_message)) 219 | # define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline)) 220 | # define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused)) 221 | # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility)) 222 | # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ 223 | (__has_attribute(warn_unused_result)) 224 | 225 | # define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16)) 226 | # define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32)) 227 | # define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64)) 228 | # define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz)) 229 | # define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz)) 230 | # define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect)) 231 | # define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address)) 232 | # define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount)) 233 | # define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_overflow)) 234 | # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow)) 235 | # define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow)) 236 | 237 | # define V8_HAS_CXX11_ALIGNAS (__has_feature(cxx_alignas)) 238 | 239 | #elif defined(__GNUC__) 240 | 241 | # define V8_CC_GNU 1 242 | # if defined(__INTEL_COMPILER) // Intel C++ also masquerades as GCC 3.2.0 243 | # define V8_CC_INTEL 1 244 | # endif 245 | # if defined(__MINGW32__) 246 | # define V8_CC_MINGW32 1 247 | # endif 248 | # if defined(__MINGW64__) 249 | # define V8_CC_MINGW64 1 250 | # endif 251 | # define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64) 252 | 253 | # define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(4, 3, 0)) 254 | 255 | # define V8_HAS_ATTRIBUTE_ALIGNED (V8_GNUC_PREREQ(2, 95, 0)) 256 | // always_inline is available in gcc 4.0 but not very reliable until 4.4. 257 | // Works around "sorry, unimplemented: inlining failed" build errors with 258 | // older compilers. 259 | # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 4, 0)) 260 | # define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0)) 261 | # define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE (V8_GNUC_PREREQ(4, 5, 0)) 262 | # define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0)) 263 | # define V8_HAS_ATTRIBUTE_UNUSED (V8_GNUC_PREREQ(2, 95, 0)) 264 | # define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0)) 265 | # define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \ 266 | (!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0)) 267 | 268 | # define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0)) 269 | # define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0)) 270 | # define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0)) 271 | # define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0)) 272 | # define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0)) 273 | 274 | # if __cplusplus >= 201103L 275 | # define V8_HAS_CXX11_ALIGNAS (V8_GNUC_PREREQ(4, 8, 0)) 276 | # define V8_HAS_CXX11_ALIGNOF (V8_GNUC_PREREQ(4, 8, 0)) 277 | # endif 278 | #endif 279 | 280 | #if defined(_MSC_VER) 281 | # define V8_CC_MSVC 1 282 | # define V8_HAS___ALIGNOF 1 283 | 284 | # define V8_HAS_DECLSPEC_ALIGN 1 285 | # define V8_HAS_DECLSPEC_DEPRECATED 1 286 | # define V8_HAS_DECLSPEC_NOINLINE 1 287 | # define V8_HAS_DECLSPEC_SELECTANY 1 288 | # define V8_HAS_DECLSPEC_NORETURN 1 289 | 290 | # define V8_HAS___FORCEINLINE 1 291 | 292 | #endif 293 | 294 | 295 | // ----------------------------------------------------------------------------- 296 | // Helper macros 297 | 298 | // A macro used to make better inlining. Don't bother for debug builds. 299 | // Use like: 300 | // V8_INLINE int GetZero() { return 0; } 301 | #if !defined(DEBUG) && V8_HAS_ATTRIBUTE_ALWAYS_INLINE 302 | # define V8_INLINE inline __attribute__((always_inline)) 303 | #elif !defined(DEBUG) && V8_HAS___FORCEINLINE 304 | # define V8_INLINE __forceinline 305 | #else 306 | # define V8_INLINE inline 307 | #endif 308 | 309 | 310 | // A macro used to tell the compiler to never inline a particular function. 311 | // Don't bother for debug builds. 312 | // Use like: 313 | // V8_NOINLINE int GetMinusOne() { return -1; } 314 | #if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE 315 | # define V8_NOINLINE __attribute__((noinline)) 316 | #elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE 317 | # define V8_NOINLINE __declspec(noinline) 318 | #else 319 | # define V8_NOINLINE /* NOT SUPPORTED */ 320 | #endif 321 | 322 | 323 | // A macro (V8_DEPRECATED) to mark classes or functions as deprecated. 324 | #if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE 325 | #define V8_DEPRECATED(message, declarator) \ 326 | declarator __attribute__((deprecated(message))) 327 | #elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED 328 | #define V8_DEPRECATED(message, declarator) \ 329 | declarator __attribute__((deprecated)) 330 | #elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED 331 | #define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator 332 | #else 333 | #define V8_DEPRECATED(message, declarator) declarator 334 | #endif 335 | 336 | 337 | // A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated. 338 | #if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \ 339 | V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE 340 | #define V8_DEPRECATE_SOON(message, declarator) \ 341 | declarator __attribute__((deprecated(message))) 342 | #elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED 343 | #define V8_DEPRECATE_SOON(message, declarator) \ 344 | declarator __attribute__((deprecated)) 345 | #elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED 346 | #define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator 347 | #else 348 | #define V8_DEPRECATE_SOON(message, declarator) declarator 349 | #endif 350 | 351 | 352 | // A macro to provide the compiler with branch prediction information. 353 | #if V8_HAS_BUILTIN_EXPECT 354 | # define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0)) 355 | # define V8_LIKELY(condition) (__builtin_expect(!!(condition), 1)) 356 | #else 357 | # define V8_UNLIKELY(condition) (condition) 358 | # define V8_LIKELY(condition) (condition) 359 | #endif 360 | 361 | 362 | // This macro allows to specify memory alignment for structs, classes, etc. 363 | // Use like: 364 | // class V8_ALIGNED(16) MyClass { ... }; 365 | // V8_ALIGNED(32) int array[42]; 366 | #if V8_HAS_CXX11_ALIGNAS 367 | # define V8_ALIGNED(n) alignas(n) 368 | #elif V8_HAS_ATTRIBUTE_ALIGNED 369 | # define V8_ALIGNED(n) __attribute__((aligned(n))) 370 | #elif V8_HAS_DECLSPEC_ALIGN 371 | # define V8_ALIGNED(n) __declspec(align(n)) 372 | #else 373 | # define V8_ALIGNED(n) /* NOT SUPPORTED */ 374 | #endif 375 | 376 | 377 | // This macro is similar to V8_ALIGNED(), but takes a type instead of size 378 | // in bytes. If the compiler does not supports using the alignment of the 379 | // |type|, it will align according to the |alignment| instead. For example, 380 | // Visual Studio C++ cannot combine __declspec(align) and __alignof. The 381 | // |alignment| must be a literal that is used as a kind of worst-case fallback 382 | // alignment. 383 | // Use like: 384 | // struct V8_ALIGNAS(AnotherClass, 16) NewClass { ... }; 385 | // V8_ALIGNAS(double, 8) int array[100]; 386 | #if V8_HAS_CXX11_ALIGNAS 387 | # define V8_ALIGNAS(type, alignment) alignas(type) 388 | #elif V8_HAS___ALIGNOF__ && V8_HAS_ATTRIBUTE_ALIGNED 389 | # define V8_ALIGNAS(type, alignment) __attribute__((aligned(__alignof__(type)))) 390 | #else 391 | # define V8_ALIGNAS(type, alignment) V8_ALIGNED(alignment) 392 | #endif 393 | 394 | 395 | // This macro returns alignment in bytes (an integer power of two) required for 396 | // any instance of the given type, which is either complete type, an array type, 397 | // or a reference type. 398 | // Use like: 399 | // size_t alignment = V8_ALIGNOF(double); 400 | #if V8_HAS_CXX11_ALIGNOF 401 | # define V8_ALIGNOF(type) alignof(type) 402 | #elif V8_HAS___ALIGNOF 403 | # define V8_ALIGNOF(type) __alignof(type) 404 | #elif V8_HAS___ALIGNOF__ 405 | # define V8_ALIGNOF(type) __alignof__(type) 406 | #else 407 | // Note that alignment of a type within a struct can be less than the 408 | // alignment of the type stand-alone (because of ancient ABIs), so this 409 | // should only be used as a last resort. 410 | namespace v8 { template class AlignOfHelper { char c; T t; }; } 411 | # define V8_ALIGNOF(type) (sizeof(::v8::AlignOfHelper) - sizeof(type)) 412 | #endif 413 | 414 | // Annotate a function indicating the caller must examine the return value. 415 | // Use like: 416 | // int foo() V8_WARN_UNUSED_RESULT; 417 | #if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT 418 | #define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 419 | #else 420 | #define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */ 421 | #endif 422 | 423 | // clang-format on 424 | 425 | #endif // V8CONFIG_H_ 426 | --------------------------------------------------------------------------------