use crate::jsc::jsc_sys::{JSContextRef, JSValueRef};
use std::os::raw::c_int;
#[cfg(feature = "vendor_jsc")]
unsafe extern "C" {
pub(crate) fn v82jsc_proxy_handler(
ctx: JSContextRef,
value: JSValueRef,
) -> JSValueRef;
pub(crate) fn v82jsc_promise_status(
ctx: JSContextRef,
value: JSValueRef,
result_out: *mut JSValueRef,
) -> c_int;
pub(crate) fn v82jsc_iterator_preview(
ctx: JSContextRef,
value: JSValueRef,
is_key_value_out: *mut bool,
) -> JSValueRef;
}
#[cfg(not(feature = "vendor_jsc"))]
pub(crate) use fallback::{
v82jsc_iterator_preview, v82jsc_promise_status, v82jsc_proxy_handler,
};
#[cfg(not(feature = "vendor_jsc"))]
mod fallback {
use super::{JSContextRef, JSValueRef, c_int};
use crate::jsc::jsc_sys::*;
use std::os::raw::c_char;
use std::ptr;
pub(crate) unsafe fn v82jsc_proxy_handler(
_ctx: JSContextRef,
_value: JSValueRef,
) -> JSValueRef {
ptr::null()
}
pub(crate) unsafe fn v82jsc_promise_status(
ctx: JSContextRef,
value: JSValueRef,
result_out: *mut JSValueRef,
) -> c_int {
if !result_out.is_null() {
unsafe { *result_out = ptr::null() };
}
if !unsafe { is_promise(ctx, value) } {
return -1;
}
let obj = value as JSObjectRef;
if !result_out.is_null() {
let r = unsafe { read_prop(ctx, obj, b"__v8jsc_result\0") };
if !r.is_null() && !unsafe { JSValueIsUndefined(ctx, r) } {
unsafe { *result_out = r };
}
}
let sv = unsafe { read_prop(ctx, obj, b"__v8jsc_state\0") };
if sv.is_null() || unsafe { JSValueIsUndefined(ctx, sv) } {
return 0;
}
let mut exc: JSValueRef = ptr::null();
match unsafe { JSValueToNumber(ctx, sv, &mut exc) } as i32 {
1 => 1,
2 => 2,
_ => 0,
}
}
unsafe fn read_prop(
ctx: JSContextRef,
obj: JSObjectRef,
name: &[u8],
) -> JSValueRef {
let key =
unsafe { JSStringCreateWithUTF8CString(name.as_ptr() as *const c_char) };
let mut exc: JSValueRef = ptr::null();
let v = unsafe { JSObjectGetProperty(ctx, obj, key, &mut exc) };
unsafe { JSStringRelease(key) };
v
}
pub(crate) unsafe fn v82jsc_iterator_preview(
_ctx: JSContextRef,
_value: JSValueRef,
_is_key_value_out: *mut bool,
) -> JSValueRef {
ptr::null()
}
unsafe fn is_promise(ctx: JSContextRef, value: JSValueRef) -> bool {
let src =
b"(function(v){try{return Object.prototype.toString.call(v)===\"[object Promise]\";}catch(e){return false;}})\0";
let mut exc: JSValueRef = ptr::null();
let fs =
unsafe { JSStringCreateWithUTF8CString(src.as_ptr() as *const c_char) };
let fnv = unsafe {
JSEvaluateScript(ctx, fs, ptr::null_mut(), ptr::null_mut(), 1, &mut exc)
};
unsafe { JSStringRelease(fs) };
if !exc.is_null() {
return false;
}
let fnobj = unsafe { JSValueToObject(ctx, fnv, &mut exc) };
if fnobj.is_null() {
return false;
}
let args = [value];
let r = unsafe {
JSObjectCallAsFunction(
ctx,
fnobj,
ptr::null_mut(),
1,
args.as_ptr(),
&mut exc,
)
};
if !exc.is_null() {
return false;
}
unsafe { JSValueToBoolean(ctx, r) }
}
}