Skip to main content

v8/
script.rs

1use std::marker::PhantomData;
2use std::mem::MaybeUninit;
3use std::ptr::null;
4
5use crate::Context;
6use crate::Data;
7use crate::Local;
8use crate::Script;
9use crate::String;
10use crate::UnboundScript;
11use crate::Value;
12use crate::scope::PinScope;
13
14/// The origin, within a file, of a script.
15#[repr(C)]
16#[derive(Debug)]
17pub struct ScriptOrigin<'s>(
18  [u8; crate::binding::v8__ScriptOrigin_SIZE],
19  PhantomData<&'s ()>,
20);
21
22unsafe extern "C" {
23  fn v8__Script__Compile(
24    context: *const Context,
25    source: *const String,
26    origin: *const ScriptOrigin,
27  ) -> *const Script;
28  fn v8__Script__GetUnboundScript(
29    script: *const Script,
30  ) -> *const UnboundScript;
31  fn v8__Script__Run(
32    script: *const Script,
33    context: *const Context,
34  ) -> *const Value;
35
36  fn v8__ScriptOrigin__CONSTRUCT(
37    buf: *mut MaybeUninit<ScriptOrigin>,
38    resource_name: *const Value,
39    resource_line_offset: i32,
40    resource_column_offset: i32,
41    resource_is_shared_cross_origin: bool,
42    script_id: i32,
43    source_map_url: *const Value,
44    resource_is_opaque: bool,
45    is_wasm: bool,
46    is_module: bool,
47    host_defined_options: *const Data,
48  );
49  fn v8__ScriptOrigin__ScriptId(origin: *const ScriptOrigin) -> i32;
50  fn v8__ScriptOrigin__ResourceName(
51    origin: *const ScriptOrigin,
52  ) -> *const Value;
53  fn v8__ScriptOrigin__SourceMapUrl(
54    origin: *const ScriptOrigin,
55  ) -> *const Value;
56}
57
58impl Script {
59  /// A shorthand for ScriptCompiler::Compile().
60  #[inline(always)]
61  pub fn compile<'s>(
62    scope: &PinScope<'s, '_>,
63    source: Local<String>,
64    origin: Option<&ScriptOrigin>,
65  ) -> Option<Local<'s, Script>> {
66    unsafe {
67      scope.cast_local(|sd| {
68        v8__Script__Compile(
69          sd.get_current_context(),
70          &*source,
71          origin.map_or_else(null, |r| r as *const _),
72        )
73      })
74    }
75  }
76
77  /// Returns the corresponding context-unbound script.
78  #[inline(always)]
79  pub fn get_unbound_script<'s>(
80    &self,
81    scope: &PinScope<'s, '_>,
82  ) -> Local<'s, UnboundScript> {
83    unsafe {
84      scope
85        .cast_local(|_| v8__Script__GetUnboundScript(self))
86        .unwrap()
87    }
88  }
89
90  /// Runs the script returning the resulting value. It will be run in the
91  /// context in which it was created (ScriptCompiler::CompileBound or
92  /// UnboundScript::BindToCurrentContext()).
93  #[inline]
94  pub fn run<'s>(&self, scope: &PinScope<'s, '_>) -> Option<Local<'s, Value>> {
95    unsafe {
96      scope.cast_local(|sd| v8__Script__Run(self, sd.get_current_context()))
97    }
98  }
99}
100
101/// The origin, within a file, of a script.
102impl<'s> ScriptOrigin<'s> {
103  #[allow(clippy::too_many_arguments)]
104  #[inline(always)]
105  pub fn new<'i>(
106    // TODO(littledivy): remove
107    _scope: &PinScope<'s, 'i>,
108    resource_name: Local<'s, Value>,
109    resource_line_offset: i32,
110    resource_column_offset: i32,
111    resource_is_shared_cross_origin: bool,
112    script_id: i32,
113    source_map_url: Option<Local<'s, Value>>,
114    resource_is_opaque: bool,
115    is_wasm: bool,
116    is_module: bool,
117    host_defined_options: Option<Local<'s, Data>>,
118  ) -> Self {
119    unsafe {
120      let mut buf = std::mem::MaybeUninit::<ScriptOrigin>::uninit();
121      v8__ScriptOrigin__CONSTRUCT(
122        &mut buf,
123        &*resource_name,
124        resource_line_offset,
125        resource_column_offset,
126        resource_is_shared_cross_origin,
127        script_id,
128        source_map_url.map_or_else(null, |l| &*l as *const Value),
129        resource_is_opaque,
130        is_wasm,
131        is_module,
132        host_defined_options.map_or_else(null, |l| &*l as *const Data),
133      );
134      buf.assume_init()
135    }
136  }
137
138  #[inline(always)]
139  pub fn script_id(&self) -> i32 {
140    unsafe { v8__ScriptOrigin__ScriptId(self as *const _) }
141  }
142
143  #[inline(always)]
144  pub fn resource_name(&self) -> Option<Local<'s, Value>> {
145    unsafe {
146      let ptr = v8__ScriptOrigin__ResourceName(self);
147      Local::from_raw(ptr)
148    }
149  }
150
151  #[inline(always)]
152  pub fn source_map_url(&self) -> Option<Local<'s, Value>> {
153    unsafe {
154      let ptr = v8__ScriptOrigin__SourceMapUrl(self);
155      Local::from_raw(ptr)
156    }
157  }
158}