Lots of places were assuming that bool and c int were interchangeable, but of course on windows a c int is 32 bits and that confused everybody. Tighten up the definitions in static-functions, which causes us to fix boolean conversion. Also add tests for boolean conversion, and also add better debug formatting of JS values.
83 lines
2.6 KiB
Rust
83 lines
2.6 KiB
Rust
#![allow(non_upper_case_globals)]
|
|
#![allow(non_camel_case_types)]
|
|
#![allow(non_snake_case)]
|
|
|
|
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
|
include!("static-functions.rs");
|
|
|
|
use std::fmt;
|
|
|
|
fn tag_name(tag: i64) -> &'static str {
|
|
match tag.try_into() {
|
|
Ok(tag) => match tag {
|
|
JS_TAG_BIG_DECIMAL => "JS_TAG_BIG_DECIMAL",
|
|
JS_TAG_BIG_INT => "JS_TAG_BIG_INT",
|
|
JS_TAG_BIG_FLOAT => "JS_TAG_BIG_FLOAT",
|
|
JS_TAG_SYMBOL => "JS_TAG_SYMBOL",
|
|
JS_TAG_MODULE => "JS_TAG_MODULE",
|
|
JS_TAG_FUNCTION_BYTECODE => "JS_TAG_FUNCTION_BYTECODE",
|
|
JS_TAG_STRING => "JS_TAG_STRING",
|
|
JS_TAG_OBJECT => "JS_TAG_OBJECT",
|
|
JS_TAG_INT => "JS_TAG_INT",
|
|
JS_TAG_BOOL => "JS_TAG_BOOL",
|
|
JS_TAG_NULL => "JS_TAG_NULL",
|
|
JS_TAG_UNDEFINED => "JS_TAG_UNDEFINED",
|
|
JS_TAG_UNINITIALIZED => "JS_TAG_UNINITIALIZED",
|
|
JS_TAG_CATCH_OFFSET => "JS_TAG_CATCH_OFFSET",
|
|
JS_TAG_EXCEPTION => "JS_TAG_EXCEPTION",
|
|
JS_TAG_FLOAT64 => "JS_TAG_FLOAT64",
|
|
_ => "???",
|
|
},
|
|
Err(_) => "???",
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for JSValue {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "JS[{} ({})", tag_name(self.tag), self.tag)?;
|
|
if self.tag < 0 {
|
|
write!(f, " {:?}]", unsafe { self.u.ptr })
|
|
} else {
|
|
write!(f, " {}]", unsafe { self.u.int32 })
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use std::ffi::CStr;
|
|
|
|
// Small sanity test that starts the runtime and evaluates code.
|
|
#[test]
|
|
fn test_eval() {
|
|
unsafe {
|
|
let rt = JS_NewRuntime();
|
|
let ctx = JS_NewContext(rt);
|
|
|
|
let code_str = "1 + 1\0";
|
|
let code = CStr::from_bytes_with_nul(code_str.as_bytes()).unwrap();
|
|
let script = CStr::from_bytes_with_nul("script\0".as_bytes()).unwrap();
|
|
|
|
let value = JS_Eval(
|
|
ctx,
|
|
code.as_ptr(),
|
|
(code_str.len() - 1).try_into().unwrap(),
|
|
script.as_ptr(),
|
|
JS_EVAL_TYPE_GLOBAL as i32,
|
|
);
|
|
assert_eq!(value.tag, 0);
|
|
assert_eq!(value.u.int32, 2);
|
|
|
|
JS_DupValue(ctx, value);
|
|
JS_FreeValue(ctx, value);
|
|
|
|
let ival = JS_NewInt32(ctx, 12);
|
|
assert_eq!(ival.tag, 0);
|
|
let fval = JS_NewFloat64(ctx, f64::MAX);
|
|
assert_eq!(fval.tag, 7);
|
|
let bval = JS_NewBool(ctx, true);
|
|
assert_eq!(bval.tag, 1);
|
|
}
|
|
}
|
|
}
|