char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
d71572b
main
1use std:: pin:: pin; 2 3struct Formatter ( v8:: Global < v8:: Function >); 4 5# [ cfg ( not ( target_os = "windows" ))] 6# [ repr ( C )] 7struct CallbackResult ( * const v8:: Value ); 8 9# [ cfg ( not ( target_os = "windows" ))] 10type Callback =unsafe extern "C" fn ( 11 v8:: Local < v8:: Context >, 12 v8:: Local < v8:: Value >, 13 v8:: Local < v8:: Array >, 14) ->CallbackResult ; 15 16# [ cfg ( target_os = "windows" )] 17type Callback =unsafe extern "C" fn ( 18* mut * const v8:: Value , 19 v8:: Local < v8:: Context >, 20 v8:: Local < v8:: Value >, 21 v8:: Local < v8:: Array >, 22) ->* mut * const v8:: Value ; 23 24unsafe extern "C" { 25fn v8__Isolate__SetPrepareStackTraceCallback ( 26isolate : v8:: UnsafeRawIsolatePtr , 27callback : Option < Callback >, 28); 29} 30 31/// Restores V8's own formatting until another context installs a formatter. 32pub ( crate ) fn clear ( isolate : & mut v8:: Isolate ) { 33// SAFETY: isolate is live, and a null callback disables custom formatting. 34unsafe { 35v8__Isolate__SetPrepareStackTraceCallback ( isolate. as_raw_isolate_ptr (), None ); 36} 37 isolate. remove_slot ::< Formatter >(); 38} 39 40pub ( crate ) fn init ( scope : & mut v8:: PinScope , formatter : v8:: Local < v8:: Function >) { 41 scope. set_slot ( Formatter ( v8:: Global :: new ( scope, formatter))); 42// rusty_v8's safe adapter cannot return an empty MaybeLocal on exceptions, 43// causing V8 to cache undefined. Mirror its ABI until it supports Option<Local>. 44// SAFETY: scope provides a live isolate, and callback matches the platform-specific 45// PrepareStackTraceCallback ABI, including its pointer-sized MaybeLocal result. 46unsafe { 47v8__Isolate__SetPrepareStackTraceCallback ( scope. as_raw_isolate_ptr (), Some ( callback)); 48} 49} 50 51fn format < ' s >( 52context : v8:: Local < ' s , v8:: Context >, 53error : v8:: Local < ' s , v8:: Value >, 54frames : v8:: Local < ' s , v8:: Array >, 55) ->* const v8:: Value { 56// SAFETY: These handles and the entered isolate/context are supplied by V8 itself. 57let scope =pin! ( unsafe { v8:: CallbackScope :: new ( context) }); 58let scope = scope. init (); 59let formatter = scope. get_slot ::< Formatter >(). unwrap (). 0 . clone (); 60let formatter = v8:: Local :: new ( & scope, formatter); 61let receiver = v8:: undefined ( & scope). into (); 62 formatter 63. call ( & scope, receiver, & [ error, frames. into ()]) 64. map_or ( std:: ptr:: null (), |value|&* valueas * const _ ) 65} 66 67# [ cfg ( not ( target_os = "windows" ))] 68unsafe extern "C" fn callback ( 69context : v8:: Local < v8:: Context >, 70error : v8:: Local < v8:: Value >, 71frames : v8:: Local < v8:: Array >, 72) ->CallbackResult { 73CallbackResult ( format ( context, error, frames)) 74} 75 76# [ cfg ( target_os = "windows" )] 77unsafe extern "C" fn callback ( 78result : * mut * const v8:: Value , 79context : v8:: Local < v8:: Context >, 80error : v8:: Local < v8:: Value >, 81frames : v8:: Local < v8:: Array >, 82) ->* mut * const v8:: Value { 83// SAFETY: V8 supplies storage for its MaybeLocal return value on Windows. 84// It is non-null, aligned, and writable for one pointer until the callback returns. 85unsafe { 86 result. write ( format ( context, error, frames)); 87} 88 result 89}