0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-11-25 15:29:43 -05:00

Add more ScriptCompiler APIs (#638)

This commit is contained in:
Heyang Zhou 2021-03-07 21:05:50 +08:00 committed by GitHub
parent e4308bb0bd
commit a6d36d1193
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 158 additions and 18 deletions

View file

@ -353,10 +353,15 @@ void v8__Global__Reset(const v8::Data* data) {
void v8__ScriptCompiler__Source__CONSTRUCT( void v8__ScriptCompiler__Source__CONSTRUCT(
uninit_t<v8::ScriptCompiler::Source>* buf, const v8::String& source_string, uninit_t<v8::ScriptCompiler::Source>* buf, const v8::String& source_string,
const v8::ScriptOrigin& origin, const v8::ScriptOrigin* origin,
v8::ScriptCompiler::CachedData* cached_data) { v8::ScriptCompiler::CachedData* cached_data) {
if (origin) {
construct_in_place<v8::ScriptCompiler::Source>( construct_in_place<v8::ScriptCompiler::Source>(
buf, ptr_to_local(&source_string), origin, cached_data); buf, ptr_to_local(&source_string), *origin, cached_data);
} else {
construct_in_place<v8::ScriptCompiler::Source>(
buf, ptr_to_local(&source_string), cached_data);
}
} }
void v8__ScriptCompiler__Source__DESTRUCT(v8::ScriptCompiler::Source* self) { void v8__ScriptCompiler__Source__DESTRUCT(v8::ScriptCompiler::Source* self) {
@ -388,6 +393,25 @@ const v8::Module* v8__ScriptCompiler__CompileModule(
return maybe_local_to_ptr(maybe_local); return maybe_local_to_ptr(maybe_local);
} }
const v8::Script* v8__ScriptCompiler__Compile(
const v8::Context* context, v8::ScriptCompiler::Source* source,
v8::ScriptCompiler::CompileOptions options,
v8::ScriptCompiler::NoCacheReason no_cache_reason) {
v8::MaybeLocal<v8::Script> maybe_local = v8::ScriptCompiler::Compile(
ptr_to_local(context), source, options, no_cache_reason);
return maybe_local_to_ptr(maybe_local);
}
const v8::UnboundScript* v8__ScriptCompiler__CompileUnboundScript(
v8::Isolate* isolate, v8::ScriptCompiler::Source* source,
v8::ScriptCompiler::CompileOptions options,
v8::ScriptCompiler::NoCacheReason no_cache_reason) {
v8::MaybeLocal<v8::UnboundScript> maybe_local =
v8::ScriptCompiler::CompileUnboundScript(isolate, source, options,
no_cache_reason);
return maybe_local_to_ptr(maybe_local);
}
bool v8__Data__EQ(const v8::Data& self, const v8::Data& other) { bool v8__Data__EQ(const v8::Data& self, const v8::Data& other) {
return ptr_to_local(&self) == ptr_to_local(&other); return ptr_to_local(&self) == ptr_to_local(&other);
} }

View file

@ -1,11 +1,11 @@
// Copyright 2019-2021 the Deno authors. All rights reserved. MIT license. // Copyright 2019-2021 the Deno authors. All rights reserved. MIT license.
use std::{marker::PhantomData, mem::MaybeUninit}; use std::{marker::PhantomData, mem::MaybeUninit};
use crate::Isolate;
use crate::Local; use crate::Local;
use crate::Module; use crate::Module;
use crate::ScriptOrigin; use crate::ScriptOrigin;
use crate::String; use crate::String;
use crate::{Context, Isolate, Script, UnboundScript};
use crate::{HandleScope, UniqueRef}; use crate::{HandleScope, UniqueRef};
extern "C" { extern "C" {
@ -30,6 +30,18 @@ extern "C" {
options: CompileOptions, options: CompileOptions,
no_cache_reason: NoCacheReason, no_cache_reason: NoCacheReason,
) -> *const Module; ) -> *const Module;
fn v8__ScriptCompiler__Compile(
context: *const Context,
source: *mut Source,
options: CompileOptions,
no_cache_reason: NoCacheReason,
) -> *const Script;
fn v8__ScriptCompiler__CompileUnboundScript(
isolate: *mut Isolate,
source: *mut Source,
options: CompileOptions,
no_cache_reason: NoCacheReason,
) -> *const UnboundScript;
} }
/// Source code which can then be compiled to a UnboundScript or Script. /// Source code which can then be compiled to a UnboundScript or Script.
@ -85,13 +97,16 @@ enum BufferPolicy {
} }
impl Source { impl Source {
pub fn new(source_string: Local<String>, origin: &ScriptOrigin) -> Self { pub fn new(
source_string: Local<String>,
origin: Option<&ScriptOrigin>,
) -> Self {
let mut buf = MaybeUninit::<Self>::uninit(); let mut buf = MaybeUninit::<Self>::uninit();
unsafe { unsafe {
v8__ScriptCompiler__Source__CONSTRUCT( v8__ScriptCompiler__Source__CONSTRUCT(
&mut buf, &mut buf,
&*source_string, &*source_string,
origin, origin.map(|x| x as *const _).unwrap_or(std::ptr::null()),
std::ptr::null_mut(), std::ptr::null_mut(),
); );
buf.assume_init() buf.assume_init()
@ -100,7 +115,7 @@ impl Source {
pub fn new_with_cached_data( pub fn new_with_cached_data(
source_string: Local<String>, source_string: Local<String>,
origin: &ScriptOrigin, origin: Option<&ScriptOrigin>,
cached_data: UniqueRef<CachedData>, cached_data: UniqueRef<CachedData>,
) -> Self { ) -> Self {
let mut buf = MaybeUninit::<Self>::uninit(); let mut buf = MaybeUninit::<Self>::uninit();
@ -108,7 +123,7 @@ impl Source {
v8__ScriptCompiler__Source__CONSTRUCT( v8__ScriptCompiler__Source__CONSTRUCT(
&mut buf, &mut buf,
&*source_string, &*source_string,
origin, origin.map(|x| x as *const _).unwrap_or(std::ptr::null()),
cached_data.into_raw(), // Source constructor takes ownership. cached_data.into_raw(), // Source constructor takes ownership.
); );
buf.assume_init() buf.assume_init()
@ -190,3 +205,39 @@ pub fn compile_module2<'s>(
}) })
} }
} }
pub fn compile<'s>(
scope: &mut HandleScope<'s>,
mut source: Source,
options: CompileOptions,
no_cache_reason: NoCacheReason,
) -> Option<Local<'s, Script>> {
unsafe {
scope.cast_local(|sd| {
v8__ScriptCompiler__Compile(
&*sd.get_current_context(),
&mut source,
options,
no_cache_reason,
)
})
}
}
pub fn compile_unbound_script<'s>(
scope: &mut HandleScope<'s>,
mut source: Source,
options: CompileOptions,
no_cache_reason: NoCacheReason,
) -> Option<Local<'s, UnboundScript>> {
unsafe {
scope.cast_local(|sd| {
v8__ScriptCompiler__CompileUnboundScript(
sd.get_isolate_ptr(),
&mut source,
options,
no_cache_reason,
)
})
}
}

View file

@ -1911,7 +1911,7 @@ fn mock_source<'s>(
) -> v8::script_compiler::Source { ) -> v8::script_compiler::Source {
let source_str = v8::String::new(scope, source).unwrap(); let source_str = v8::String::new(scope, source).unwrap();
let script_origin = mock_script_origin(scope, resource_name); let script_origin = mock_script_origin(scope, resource_name);
v8::script_compiler::Source::new(source_str, &script_origin) v8::script_compiler::Source::new(source_str, Some(&script_origin))
} }
#[test] #[test]
@ -1928,7 +1928,7 @@ fn script_compiler_source() {
let script_origin = mock_script_origin(scope, "foo.js"); let script_origin = mock_script_origin(scope, "foo.js");
let source = v8::script_compiler::Source::new( let source = v8::script_compiler::Source::new(
v8::String::new(scope, source).unwrap(), v8::String::new(scope, source).unwrap(),
&script_origin, Some(&script_origin),
); );
let result = v8::script_compiler::compile_module(scope, source); let result = v8::script_compiler::compile_module(scope, source);
@ -1952,7 +1952,7 @@ fn module_instantiation_failures1() {
) )
.unwrap(); .unwrap();
let origin = mock_script_origin(scope, "foo.js"); let origin = mock_script_origin(scope, "foo.js");
let source = v8::script_compiler::Source::new(source_text, &origin); let source = v8::script_compiler::Source::new(source_text, Some(&origin));
let module = v8::script_compiler::compile_module(scope, source).unwrap(); let module = v8::script_compiler::compile_module(scope, source).unwrap();
assert_eq!(v8::ModuleStatus::Uninstantiated, module.get_status()); assert_eq!(v8::ModuleStatus::Uninstantiated, module.get_status());
@ -2015,7 +2015,7 @@ fn compile_specifier_as_module_resolve_callback<'a>(
) -> Option<v8::Local<'a, v8::Module>> { ) -> Option<v8::Local<'a, v8::Module>> {
let scope = &mut unsafe { v8::CallbackScope::new(context) }; let scope = &mut unsafe { v8::CallbackScope::new(context) };
let origin = mock_script_origin(scope, "module.js"); let origin = mock_script_origin(scope, "module.js");
let source = v8::script_compiler::Source::new(specifier, &origin); let source = v8::script_compiler::Source::new(specifier, Some(&origin));
let module = v8::script_compiler::compile_module(scope, source).unwrap(); let module = v8::script_compiler::compile_module(scope, source).unwrap();
Some(module) Some(module)
} }
@ -2036,7 +2036,7 @@ fn module_evaluation() {
) )
.unwrap(); .unwrap();
let origin = mock_script_origin(scope, "foo.js"); let origin = mock_script_origin(scope, "foo.js");
let source = v8::script_compiler::Source::new(source_text, &origin); let source = v8::script_compiler::Source::new(source_text, Some(&origin));
let module = v8::script_compiler::compile_module(scope, source).unwrap(); let module = v8::script_compiler::compile_module(scope, source).unwrap();
assert!(module.script_id().is_some()); assert!(module.script_id().is_some());
@ -2088,7 +2088,7 @@ fn import_assertions() {
let origin = mock_script_origin(scope, "module.js"); let origin = mock_script_origin(scope, "module.js");
let src = v8::String::new(scope, "export const a = 'a';").unwrap(); let src = v8::String::new(scope, "export const a = 'a';").unwrap();
let source = v8::script_compiler::Source::new(src, &origin); let source = v8::script_compiler::Source::new(src, Some(&origin));
let module = v8::script_compiler::compile_module(scope, source).unwrap(); let module = v8::script_compiler::compile_module(scope, source).unwrap();
Some(module) Some(module)
} }
@ -2125,7 +2125,7 @@ fn import_assertions() {
) )
.unwrap(); .unwrap();
let origin = mock_script_origin(scope, "foo.js"); let origin = mock_script_origin(scope, "foo.js");
let source = v8::script_compiler::Source::new(source_text, &origin); let source = v8::script_compiler::Source::new(source_text, Some(&origin));
let module = v8::script_compiler::compile_module(scope, source).unwrap(); let module = v8::script_compiler::compile_module(scope, source).unwrap();
assert!(module.script_id().is_some()); assert!(module.script_id().is_some());
@ -3723,7 +3723,7 @@ fn module_snapshot() {
) )
.unwrap(); .unwrap();
let origin = mock_script_origin(scope, "foo.js"); let origin = mock_script_origin(scope, "foo.js");
let source = v8::script_compiler::Source::new(source_text, &origin); let source = v8::script_compiler::Source::new(source_text, Some(&origin));
let module = v8::script_compiler::compile_module(scope, source).unwrap(); let module = v8::script_compiler::compile_module(scope, source).unwrap();
assert_eq!(v8::ModuleStatus::Uninstantiated, module.get_status()); assert_eq!(v8::ModuleStatus::Uninstantiated, module.get_status());
@ -4807,10 +4807,10 @@ fn create_module<'s>(
let source = match code_cache { let source = match code_cache {
Some(x) => v8::script_compiler::Source::new_with_cached_data( Some(x) => v8::script_compiler::Source::new_with_cached_data(
source, source,
&script_origin, Some(&script_origin),
x, x,
), ),
None => v8::script_compiler::Source::new(source, &script_origin), None => v8::script_compiler::Source::new(source, Some(&script_origin)),
}; };
let module = v8::script_compiler::compile_module2( let module = v8::script_compiler::compile_module2(
scope, scope,
@ -4894,3 +4894,68 @@ fn code_cache() {
.unwrap(); .unwrap();
assert_eq!(&value.to_rust_string_lossy(&mut scope), "world"); assert_eq!(&value.to_rust_string_lossy(&mut scope), "world");
} }
#[test]
fn eager_compile_script() {
let _setup_guard = setup();
let isolate = &mut v8::Isolate::new(Default::default());
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope);
let scope = &mut v8::ContextScope::new(scope, context);
let code = v8::String::new(scope, "1 + 1").unwrap();
let source = v8::script_compiler::Source::new(code, None);
let script = v8::script_compiler::compile(
scope,
source,
v8::script_compiler::CompileOptions::EagerCompile,
v8::script_compiler::NoCacheReason::NoReason,
)
.unwrap();
let ret = script.run(scope).unwrap();
assert_eq!(ret.uint32_value(scope).unwrap(), 2);
}
#[test]
fn code_cache_script() {
const CODE: &str = "1 + 1";
let _setup_guard = setup();
let code_cache = {
let isolate = &mut v8::Isolate::new(Default::default());
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope);
let scope = &mut v8::ContextScope::new(scope, context);
let code = v8::String::new(scope, CODE).unwrap();
let source = v8::script_compiler::Source::new(code, None);
let script = v8::script_compiler::compile_unbound_script(
scope,
source,
v8::script_compiler::CompileOptions::EagerCompile,
v8::script_compiler::NoCacheReason::NoReason,
)
.unwrap();
script.create_code_cache().unwrap().to_vec()
};
let isolate = &mut v8::Isolate::new(Default::default());
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope);
let scope = &mut v8::ContextScope::new(scope, context);
let code = v8::String::new(scope, CODE).unwrap();
let source = v8::script_compiler::Source::new_with_cached_data(
code,
None,
v8::CachedData::new(&code_cache),
);
let script = v8::script_compiler::compile(
scope,
source,
v8::script_compiler::CompileOptions::ConsumeCodeCache,
v8::script_compiler::NoCacheReason::NoReason,
)
.unwrap();
let ret = script.run(scope).unwrap();
assert_eq!(ret.uint32_value(scope).unwrap(), 2);
}