1#![allow(non_snake_case)]
2
3use std::convert::TryInto;
4
5use crate::Context;
6use crate::Local;
7use crate::Message;
8use crate::Object;
9use crate::StackFrame;
10use crate::StackTrace;
11use crate::String;
12use crate::Value;
13use crate::isolate::RealIsolate;
14use crate::scope::PinScope;
15use crate::support::MaybeBool;
16use crate::support::int;
17
18unsafe extern "C" {
19 fn v8__Message__Get(this: *const Message) -> *const String;
20 fn v8__Message__GetSourceLine(
21 this: *const Message,
22 context: *const Context,
23 ) -> *const String;
24 fn v8__Message__GetScriptResourceName(this: *const Message) -> *const Value;
25 fn v8__Message__GetLineNumber(
26 this: *const Message,
27 context: *const Context,
28 ) -> int;
29 fn v8__Message__GetStartPosition(this: *const Message) -> int;
30 fn v8__Message__GetEndPosition(this: *const Message) -> int;
31 fn v8__Message__GetWasmFunctionIndex(this: *const Message) -> int;
32 fn v8__Message__ErrorLevel(this: *const Message) -> int;
33 fn v8__Message__GetStartColumn(this: *const Message) -> int;
34 fn v8__Message__GetEndColumn(this: *const Message) -> int;
35 fn v8__Message__IsSharedCrossOrigin(this: *const Message) -> bool;
36 fn v8__Message__IsOpaque(this: *const Message) -> bool;
37 fn v8__Message__GetStackTrace(this: *const Message) -> *const StackTrace;
38
39 fn v8__StackTrace__CurrentStackTrace(
40 isolate: *mut RealIsolate,
41 frame_limit: int,
42 ) -> *const StackTrace;
43 fn v8__StackTrace__CurrentScriptNameOrSourceURL(
44 isolate: *mut RealIsolate,
45 ) -> *const String;
46 fn v8__StackTrace__GetFrameCount(this: *const StackTrace) -> int;
47 fn v8__StackTrace__GetFrame(
48 this: *const StackTrace,
49 isolate: *mut RealIsolate,
50 index: u32,
51 ) -> *const StackFrame;
52
53 fn v8__StackFrame__GetLineNumber(this: *const StackFrame) -> int;
54 fn v8__StackFrame__GetColumn(this: *const StackFrame) -> int;
55 fn v8__StackFrame__GetScriptId(this: *const StackFrame) -> int;
56 fn v8__StackFrame__GetScriptName(this: *const StackFrame) -> *const String;
57 fn v8__StackFrame__GetScriptNameOrSourceURL(
58 this: *const StackFrame,
59 ) -> *const String;
60 fn v8__StackFrame__GetScriptSource(this: *const StackFrame) -> *const String;
61 fn v8__StackFrame__GetScriptSourceMappingURL(
62 this: *const StackFrame,
63 ) -> *const String;
64 fn v8__StackFrame__GetFunctionName(this: *const StackFrame) -> *const String;
65 fn v8__StackFrame__IsEval(this: *const StackFrame) -> bool;
66 fn v8__StackFrame__IsConstructor(this: *const StackFrame) -> bool;
67 fn v8__StackFrame__IsWasm(this: *const StackFrame) -> bool;
68 fn v8__StackFrame__IsUserJavaScript(this: *const StackFrame) -> bool;
69
70 fn v8__Exception__Error(message: *const String) -> *const Value;
71 fn v8__Exception__RangeError(message: *const String) -> *const Value;
72 fn v8__Exception__ReferenceError(message: *const String) -> *const Value;
73 fn v8__Exception__SyntaxError(message: *const String) -> *const Value;
74 fn v8__Exception__TypeError(message: *const String) -> *const Value;
75
76 fn v8__Exception__CreateMessage(
77 isolate: *mut RealIsolate,
78 exception: *const Value,
79 ) -> *const Message;
80 fn v8__Exception__GetStackTrace(exception: *const Value)
81 -> *const StackTrace;
82 fn v8__Exception__CaptureStackTrace(
83 context: *const Context,
84 object: *const Object,
85 ) -> MaybeBool;
86}
87
88impl StackTrace {
89 #[inline(always)]
91 pub fn current_stack_trace<'s>(
92 scope: &PinScope<'s, '_>,
93 frame_limit: usize,
94 ) -> Option<Local<'s, StackTrace>> {
95 let frame_limit = frame_limit.try_into().ok()?;
96 unsafe {
97 scope.cast_local(|sd| {
98 v8__StackTrace__CurrentStackTrace(sd.get_isolate_ptr(), frame_limit)
99 })
100 }
101 }
102
103 #[inline(always)]
113 pub fn current_script_name_or_source_url<'s>(
114 scope: &PinScope<'s, '_>,
115 ) -> Option<Local<'s, String>> {
116 unsafe {
117 scope.cast_local(|sd| {
118 v8__StackTrace__CurrentScriptNameOrSourceURL(sd.get_isolate_ptr())
119 })
120 }
121 }
122
123 #[inline(always)]
125 pub fn get_frame_count(&self) -> usize {
126 unsafe { v8__StackTrace__GetFrameCount(self) as usize }
127 }
128
129 #[inline(always)]
131 pub fn get_frame<'s>(
132 &self,
133 scope: &PinScope<'s, '_>,
134 index: usize,
135 ) -> Option<Local<'s, StackFrame>> {
136 unsafe {
137 scope.cast_local(|sd| {
138 v8__StackTrace__GetFrame(self, sd.get_isolate_ptr(), index as u32)
139 })
140 }
141 }
142}
143
144impl StackFrame {
145 #[inline(always)]
150 pub fn get_line_number(&self) -> usize {
151 unsafe { v8__StackFrame__GetLineNumber(self) as usize }
152 }
153
154 #[inline(always)]
160 pub fn get_column(&self) -> usize {
161 unsafe { v8__StackFrame__GetColumn(self) as usize }
162 }
163
164 #[inline(always)]
169 pub fn get_script_id(&self) -> usize {
170 unsafe { v8__StackFrame__GetScriptId(self) as usize }
171 }
172
173 #[inline(always)]
176 pub fn get_script_name<'s>(
177 &self,
178 scope: &PinScope<'s, '_>,
179 ) -> Option<Local<'s, String>> {
180 unsafe { scope.cast_local(|_| v8__StackFrame__GetScriptName(self)) }
181 }
182
183 #[inline(always)]
188 pub fn get_script_name_or_source_url<'s>(
189 &self,
190 scope: &PinScope<'s, '_>,
191 ) -> Option<Local<'s, String>> {
192 unsafe {
193 scope.cast_local(|_| v8__StackFrame__GetScriptNameOrSourceURL(self))
194 }
195 }
196
197 #[inline(always)]
199 pub fn get_script_source<'s>(
200 &self,
201 scope: &PinScope<'s, '_>,
202 ) -> Option<Local<'s, String>> {
203 unsafe { scope.cast_local(|_| v8__StackFrame__GetScriptSource(self)) }
204 }
205
206 #[inline(always)]
209 pub fn get_script_source_mapping_url<'s>(
210 &self,
211 scope: &PinScope<'s, '_>,
212 ) -> Option<Local<'s, String>> {
213 unsafe {
214 scope.cast_local(|_| v8__StackFrame__GetScriptSourceMappingURL(self))
215 }
216 }
217
218 #[inline(always)]
220 pub fn get_function_name<'s>(
221 &self,
222 scope: &PinScope<'s, '_>,
223 ) -> Option<Local<'s, String>> {
224 unsafe { scope.cast_local(|_| v8__StackFrame__GetFunctionName(self)) }
225 }
226
227 #[inline(always)]
230 pub fn is_eval(&self) -> bool {
231 unsafe { v8__StackFrame__IsEval(self) }
232 }
233
234 #[inline(always)]
237 pub fn is_constructor(&self) -> bool {
238 unsafe { v8__StackFrame__IsConstructor(self) }
239 }
240
241 #[inline(always)]
243 pub fn is_wasm(&self) -> bool {
244 unsafe { v8__StackFrame__IsWasm(self) }
245 }
246
247 #[inline(always)]
249 pub fn is_user_javascript(&self) -> bool {
250 unsafe { v8__StackFrame__IsUserJavaScript(self) }
251 }
252}
253
254impl Message {
255 #[inline(always)]
256 pub fn get<'s>(&self, scope: &PinScope<'s, '_>) -> Local<'s, String> {
257 unsafe { scope.cast_local(|_| v8__Message__Get(self)) }.unwrap()
258 }
259
260 #[inline(always)]
264 pub fn get_stack_trace<'s>(
265 &self,
266 scope: &PinScope<'s, '_>,
267 ) -> Option<Local<'s, StackTrace>> {
268 unsafe { scope.cast_local(|_| v8__Message__GetStackTrace(self)) }
269 }
270
271 #[inline(always)]
272 pub fn get_source_line<'s>(
273 &self,
274 scope: &PinScope<'s, '_>,
275 ) -> Option<Local<'s, String>> {
276 unsafe {
277 scope.cast_local(|sd| {
278 v8__Message__GetSourceLine(self, sd.get_current_context())
279 })
280 }
281 }
282
283 #[inline(always)]
286 pub fn get_script_resource_name<'s>(
287 &self,
288 scope: &PinScope<'s, '_>,
289 ) -> Option<Local<'s, Value>> {
290 unsafe { scope.cast_local(|_| v8__Message__GetScriptResourceName(self)) }
291 }
292
293 #[inline(always)]
295 pub fn get_line_number(&self, scope: &PinScope<'_, '_>) -> Option<usize> {
296 let i = unsafe {
297 v8__Message__GetLineNumber(self, &*scope.get_current_context())
298 };
299 if i < 0 { None } else { Some(i as usize) }
300 }
301
302 #[inline(always)]
305 pub fn get_start_position(&self) -> int {
306 unsafe { v8__Message__GetStartPosition(self) }
307 }
308
309 #[inline(always)]
312 pub fn get_end_position(&self) -> int {
313 unsafe { v8__Message__GetEndPosition(self) }
314 }
315
316 #[inline(always)]
319 pub fn get_wasm_function_index(&self) -> int {
320 unsafe { v8__Message__GetWasmFunctionIndex(self) }
321 }
322
323 #[inline(always)]
325 pub fn error_level(&self) -> int {
326 unsafe { v8__Message__ErrorLevel(self) }
327 }
328
329 #[inline(always)]
332 pub fn get_start_column(&self) -> usize {
333 unsafe { v8__Message__GetStartColumn(self) as usize }
334 }
335
336 #[inline(always)]
339 pub fn get_end_column(&self) -> usize {
340 unsafe { v8__Message__GetEndColumn(self) as usize }
341 }
342
343 #[inline(always)]
346 pub fn is_shared_cross_origin(&self) -> bool {
347 unsafe { v8__Message__IsSharedCrossOrigin(self) }
348 }
349
350 #[inline(always)]
351 pub fn is_opaque(&self) -> bool {
352 unsafe { v8__Message__IsOpaque(self) }
353 }
354}
355
356#[derive(Debug)]
359pub struct Exception;
360
361impl Exception {
362 #[inline(always)]
363 pub fn error<'s>(
364 scope: &PinScope<'s, '_>,
365 message: Local<String>,
366 ) -> Local<'s, Value> {
367 Self::new_error_with(scope, message, v8__Exception__Error)
368 }
369
370 #[inline(always)]
371 pub fn range_error<'s>(
372 scope: &PinScope<'s, '_>,
373 message: Local<String>,
374 ) -> Local<'s, Value> {
375 Self::new_error_with(scope, message, v8__Exception__RangeError)
376 }
377
378 #[inline(always)]
379 pub fn reference_error<'s>(
380 scope: &PinScope<'s, '_>,
381 message: Local<String>,
382 ) -> Local<'s, Value> {
383 Self::new_error_with(scope, message, v8__Exception__ReferenceError)
384 }
385
386 #[inline(always)]
387 pub fn syntax_error<'s>(
388 scope: &PinScope<'s, '_>,
389 message: Local<String>,
390 ) -> Local<'s, Value> {
391 Self::new_error_with(scope, message, v8__Exception__SyntaxError)
392 }
393
394 #[inline(always)]
395 pub fn type_error<'s>(
396 scope: &PinScope<'s, '_>,
397 message: Local<String>,
398 ) -> Local<'s, Value> {
399 Self::new_error_with(scope, message, v8__Exception__TypeError)
400 }
401
402 #[inline(always)]
404 fn new_error_with<'s>(
405 scope: &PinScope<'s, '_>,
406 message: Local<String>,
407 contructor: unsafe extern "C" fn(*const String) -> *const Value,
408 ) -> Local<'s, Value> {
409 unsafe {
410 scope.enter();
411 let error = scope.cast_local(|_| (contructor)(&*message)).unwrap();
412 scope.exit();
413 error
414 }
415 }
416
417 #[inline(always)]
421 pub fn create_message<'s>(
422 scope: &PinScope<'s, '_>,
423 exception: Local<Value>,
424 ) -> Local<'s, Message> {
425 unsafe {
426 scope.cast_local(|sd| {
427 v8__Exception__CreateMessage(sd.get_isolate_ptr(), &*exception)
428 })
429 }
430 .unwrap()
431 }
432
433 #[inline(always)]
436 pub fn get_stack_trace<'s>(
437 scope: &PinScope<'s, '_>,
438 exception: Local<Value>,
439 ) -> Option<Local<'s, StackTrace>> {
440 unsafe { scope.cast_local(|_| v8__Exception__GetStackTrace(&*exception)) }
441 }
442
443 #[inline(always)]
446 pub fn capture_stack_trace(
447 context: Local<Context>,
448 object: Local<Object>,
449 ) -> Option<bool> {
450 unsafe { v8__Exception__CaptureStackTrace(&*context, &*object).into() }
451 }
452}