Big Rewrite
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
mod ffi;
|
||||
pub mod parse;
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use parse::QuickJSBinary;
|
||||
|
||||
pub fn compile(src: &[u8], filename: &str) -> QuickJSBinary {
|
||||
unsafe {
|
||||
let filename = CString::new(filename).unwrap();
|
||||
|
||||
let rt = ffi::JS_NewRuntime();
|
||||
let ctx = ffi::JS_NewContext(rt);
|
||||
|
||||
let obj = ffi::JS_Eval(
|
||||
ctx,
|
||||
src.as_ptr(),
|
||||
src.len(),
|
||||
filename.as_ptr().cast(),
|
||||
ffi::JS_EVAL_FLAG_COMPILE_ONLY | ffi::JS_EVAL_TYPE_MODULE,
|
||||
);
|
||||
|
||||
assert!(obj.tag != ffi::JS_TAG_EXCEPTION, "{}", get_exception(ctx));
|
||||
|
||||
let mut len = 0;
|
||||
let buf = ffi::JS_WriteObject(ctx, &mut len, obj, ffi::JS_WRITE_OBJ_BYTECODE);
|
||||
ffi::JS_FreeValue(ctx, obj);
|
||||
|
||||
assert!(!buf.is_null());
|
||||
let bytes = std::slice::from_raw_parts(buf, len).to_vec();
|
||||
|
||||
// TODO: Are we sure other cleanup is not necessary?
|
||||
ffi::JS_FreeContext(ctx);
|
||||
ffi::JS_FreeRuntime(rt);
|
||||
|
||||
QuickJSBinary::parse(&bytes).unwrap().1
|
||||
}
|
||||
}
|
||||
|
||||
fn get_exception(ctx: *mut ffi::JSContext) -> String {
|
||||
unsafe {
|
||||
let err = ffi::JS_GetException(ctx);
|
||||
let text = ffi::JS_ToCStringLen2(ctx, std::ptr::null_mut(), err, false);
|
||||
|
||||
let message = if text.is_null() {
|
||||
"quickjs raised an exception it could not describe".to_string()
|
||||
} else {
|
||||
CStr::from_ptr(text).to_string_lossy().into_owned()
|
||||
};
|
||||
|
||||
message
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user