Skip to content

Commit 4a3c55d

Browse files
wip, v16 using bellard 2025-09-13
1 parent 41520ea commit 4a3c55d

File tree

10 files changed

+90
-131
lines changed

10 files changed

+90
-131
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 0.16.0
2+
3+
* update to bellard 2025-09-13
4+
* removed atom.to_str as it was badly implemented
5+
* removed string.to_str as it was badly implemented
6+
17
# 0.15.7
28

39
* updated error handling / toString (include cause and such)

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "quickjs_runtime"
3-
version = "0.15.7"
3+
version = "0.16.0"
44
authors = ["Andries Hiemstra <[email protected]>"]
55
edition = "2021"
66
description = "Wrapper API and utils for the QuickJS JavaScript engine with support for Promise, Modules, Async/await"
@@ -31,7 +31,7 @@ backtrace = "0.3"
3131

3232
#libquickjs-sys = {package="hirofa-quickjs-sys", git='https://github.com/HiRoFa/quickjs-sys'}
3333
#libquickjs-sys = { package = "hirofa-quickjs-sys", path = '../quickjs-sys', default-features = false }
34-
libquickjs-sys = { package = "hirofa-quickjs-sys", version = "0.10.0", default-features = false }
34+
libquickjs-sys = { package = "hirofa-quickjs-sys", version = "0.11", default-features = false }
3535
lazy_static = "1.5.0"
3636
log = "0.4"
3737
num_cpus = "1"

src/facades.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ pub mod tests {
11961196
let q_ctx = q_js_rt.get_main_realm();
11971197
let r = q_ctx.eval(Script::new(
11981198
"test_async.es",
1199-
"let f = async function(){let p = new Promise((resolve, reject) => {resolve(12345);}); const p2 = await p; return p2}; f();",
1199+
"let f = async function(){let p = new Promise((resolve, reject) => {resolve(12345);}); const p2 = await p; return p2}; f()",
12001200
)).ok().unwrap();
12011201
log::trace!("tag = {}", r.get_tag());
12021202
//std::thread::sleep(Duration::from_secs(1));

src/quickjs_utils/atoms.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::quickjs_utils::primitives;
44
use crate::quickjsrealmadapter::QuickJsRealmAdapter;
55
use crate::quickjsvalueadapter::QuickJsValueAdapter;
66
use libquickjs_sys as q;
7-
use std::ffi::{CStr, CString};
7+
use std::ffi::CString;
88

99
#[allow(clippy::upper_case_acronyms)]
1010
pub struct JSAtomRef {
@@ -62,16 +62,6 @@ pub unsafe fn to_string2(context: *mut q::JSContext, atom: &q::JSAtom) -> Result
6262
primitives::to_string(context, &val_ref)
6363
}
6464

65-
/// # Safety
66-
/// When passing a context pointer please make sure the corresponding QuickJsContext is still valid
67-
pub unsafe fn to_str(context: *mut q::JSContext, atom: &q::JSAtom) -> Result<&str, JsError> {
68-
let c_string = q::JS_AtomToCString(context, *atom);
69-
let c_str = CStr::from_ptr(c_string);
70-
c_str
71-
.to_str()
72-
.map_err(|e| JsError::new_string(format!("{e}")))
73-
}
74-
7565
pub fn from_string_q(q_ctx: &QuickJsRealmAdapter, string: &str) -> Result<JSAtomRef, JsError> {
7666
unsafe { from_string(q_ctx.context, string) }
7767
}

src/quickjs_utils/mod.rs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,34 @@ pub mod class_ids {
3333
pub const JS_CLASS_UINT32_ARRAY: u32 = 27;
3434
pub const JS_CLASS_BIG_INT64_ARRAY: u32 = 28;
3535
pub const JS_CLASS_BIG_UINT64_ARRAY: u32 = 29;
36-
pub const JS_CLASS_FLOAT32_ARRAY: u32 = 30;
37-
pub const JS_CLASS_FLOAT64_ARRAY: u32 = 31;
38-
pub const JS_CLASS_DATAVIEW: u32 = 32;
39-
pub const JS_CLASS_BIG_INT: u32 = 33;
40-
pub const JS_CLASS_MAP: u32 = 34;
41-
pub const JS_CLASS_SET: u32 = 35;
42-
pub const JS_CLASS_WEAKMAP: u32 = 36;
43-
pub const JS_CLASS_WEAKSET: u32 = 37;
44-
pub const JS_CLASS_MAP_ITERATOR: u32 = 38;
45-
pub const JS_CLASS_SET_ITERATOR: u32 = 39;
46-
pub const JS_CLASS_ARRAY_ITERATOR: u32 = 40;
47-
pub const JS_CLASS_STRING_ITERATOR: u32 = 41;
48-
pub const JS_CLASS_REGEXP_STRING_ITERATOR: u32 = 42;
49-
pub const JS_CLASS_GENERATOR: u32 = 43;
50-
pub const JS_CLASS_PROXY: u32 = 44;
51-
pub const JS_CLASS_PROMISE: u32 = 45;
52-
pub const JS_CLASS_PROMISE_RESOLVE_FUNCTION: u32 = 46;
53-
pub const JS_CLASS_PROMISE_REJECT_FUNCTION: u32 = 47;
54-
pub const JS_CLASS_ASYNC_FUNCTION: u32 = 48;
55-
pub const JS_CLASS_ASYNC_FUNCTION_RESOLVE: u32 = 49;
56-
pub const JS_CLASS_ASYNC_FUNCTION_REJECT: u32 = 50;
57-
pub const JS_CLASS_ASYNC_FROM_SYNC_ITERATOR: u32 = 51;
58-
pub const JS_CLASS_ASYNC_GENERATOR_FUNCTION: u32 = 52;
59-
pub const JS_CLASS_ASYNC_GENERATOR: u32 = 53;
60-
pub const JS_CLASS_WEAK_REF: u32 = 54;
61-
pub const JS_CLASS_FINALIZATION_REGISTRY: u32 = 55;
62-
pub const JS_CLASS_INIT_COUNT: u32 = 56;
36+
pub const JS_CLASS_FLOAT16_ARRAY: u32 = 30;
37+
pub const JS_CLASS_FLOAT32_ARRAY: u32 = 31;
38+
pub const JS_CLASS_FLOAT64_ARRAY: u32 = 32;
39+
pub const JS_CLASS_DATAVIEW: u32 = 33;
40+
pub const JS_CLASS_BIG_INT: u32 = 34;
41+
pub const JS_CLASS_MAP: u32 = 35;
42+
pub const JS_CLASS_SET: u32 = 36;
43+
pub const JS_CLASS_WEAKMAP: u32 = 37;
44+
pub const JS_CLASS_WEAKSET: u32 = 38;
45+
pub const JS_CLASS_MAP_ITERATOR: u32 = 39;
46+
pub const JS_CLASS_SET_ITERATOR: u32 = 40;
47+
pub const JS_CLASS_ARRAY_ITERATOR: u32 = 41;
48+
pub const JS_CLASS_STRING_ITERATOR: u32 = 42;
49+
pub const JS_CLASS_REGEXP_STRING_ITERATOR: u32 = 43;
50+
pub const JS_CLASS_GENERATOR: u32 = 44;
51+
pub const JS_CLASS_PROXY: u32 = 45;
52+
pub const JS_CLASS_PROMISE: u32 = 46;
53+
pub const JS_CLASS_PROMISE_RESOLVE_FUNCTION: u32 = 47;
54+
pub const JS_CLASS_PROMISE_REJECT_FUNCTION: u32 = 48;
55+
pub const JS_CLASS_ASYNC_FUNCTION: u32 = 49;
56+
pub const JS_CLASS_ASYNC_FUNCTION_RESOLVE: u32 = 50;
57+
pub const JS_CLASS_ASYNC_FUNCTION_REJECT: u32 = 51;
58+
pub const JS_CLASS_ASYNC_FROM_SYNC_ITERATOR: u32 = 52;
59+
pub const JS_CLASS_ASYNC_GENERATOR_FUNCTION: u32 = 53;
60+
pub const JS_CLASS_ASYNC_GENERATOR: u32 = 54;
61+
pub const JS_CLASS_WEAK_REF: u32 = 55;
62+
pub const JS_CLASS_FINALIZATION_REGISTRY: u32 = 56;
63+
pub const JS_CLASS_INIT_COUNT: u32 = 57;
6364
}
6465
#[cfg(feature = "quickjs-ng")]
6566
pub mod class_ids {

src/quickjs_utils/objects.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ where
467467

468468
for index in 0..enum_ref.len() {
469469
let atom = enum_ref.get_atom_raw(index) as q::JSAtom;
470-
let prop_name = atoms::to_str(context, &atom)?;
470+
let prop_name = atoms::to_string2(context, &atom)?;
471471

472472
#[cfg(feature = "bellard")]
473473
let raw_value = q::JS_GetPropertyInternal(
@@ -491,7 +491,7 @@ where
491491
return Err(JsError::new_str("Could not get object property"));
492492
}
493493

494-
let r = visitor(prop_name, &prop_val_ref)?;
494+
let r = visitor(prop_name.as_str(), &prop_val_ref)?;
495495

496496
result.push(r);
497497
}
@@ -513,7 +513,7 @@ where
513513

514514
for index in 0..enum_ref.len() {
515515
let atom = enum_ref.get_atom_raw(index) as q::JSAtom;
516-
let prop_name = atoms::to_str(context, &atom)?;
516+
let prop_name = atoms::to_string2(context, &atom)?;
517517

518518
#[cfg(feature = "bellard")]
519519
let raw_value = q::JS_GetPropertyInternal(
@@ -537,7 +537,7 @@ where
537537
return Err(JsError::new_str("Could not get object property"));
538538
}
539539

540-
visitor(prop_name, &prop_val_ref)?;
540+
visitor(prop_name.as_str(), &prop_val_ref)?;
541541
}
542542

543543
Ok(())

src/quickjs_utils/primitives.rs

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -90,56 +90,17 @@ pub unsafe fn to_string(
9090
));
9191
}
9292

93-
let cstr = std::ffi::CStr::from_ptr(ptr);
93+
let bytes = std::slice::from_raw_parts(ptr as *const u8, len);
9494

95-
let s = cstr.to_string_lossy().into_owned();
95+
// Convert to String (validate UTF-8).
96+
let s = String::from_utf8_lossy(bytes).into_owned();
9697

9798
// Free the c string.
9899
q::JS_FreeCString(context, ptr);
99100

100101
Ok(s)
101102
}
102103

103-
/// # Safety
104-
/// When passing a context pointer please make sure the corresponding QuickJsContext is still valid
105-
pub unsafe fn to_str(
106-
context: *mut q::JSContext,
107-
value_ref: &QuickJsValueAdapter,
108-
) -> Result<&str, JsError> {
109-
//log::trace!("primitives::to_str on {}", value_ref.borrow_value().tag);
110-
111-
assert!(value_ref.is_string());
112-
113-
let mut len = 0;
114-
115-
#[cfg(feature = "bellard")]
116-
let ptr: *const c_char = q::JS_ToCStringLen2(context, &mut len, *value_ref.borrow_value(), 0);
117-
#[cfg(feature = "quickjs-ng")]
118-
let ptr: *const c_char =
119-
q::JS_ToCStringLen2(context, &mut len, *value_ref.borrow_value(), false);
120-
// Free the c string.
121-
q::JS_FreeCString(context, ptr);
122-
// ptr should still be valid as long as value_ref lives
123-
124-
if len == 0 {
125-
return Ok("");
126-
}
127-
128-
if ptr.is_null() {
129-
return Err(JsError::new_str(
130-
"Could not convert string: got a null pointer",
131-
));
132-
}
133-
134-
let cstr = std::ffi::CStr::from_ptr(ptr);
135-
cstr.to_str()
136-
.map_err(|e| JsError::new_string(format!("utf8 error: {e}")))
137-
138-
//let s = cstr.to_string_lossy();
139-
140-
//Ok(s.as_ref())
141-
}
142-
143104
pub fn from_string_q(q_ctx: &QuickJsRealmAdapter, s: &str) -> Result<QuickJsValueAdapter, JsError> {
144105
unsafe { from_string(q_ctx.context, s) }
145106
}
@@ -160,7 +121,6 @@ pub unsafe fn from_string(
160121

161122
#[cfg(test)]
162123
pub mod tests {
163-
164124
use crate::facades::tests::init_test_rt;
165125
use crate::jsutils::Script;
166126

src/quickjs_utils/properties.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl JSPropertyEnumRef {
4646
pub fn get_name(&self, index: u32) -> Result<String, JsError> {
4747
let atom: *mut q::JSAtom = unsafe { self.get_atom_raw(index) };
4848
let atom = atom as q::JSAtom;
49-
unsafe { Ok(atoms::to_str(self.context, &atom)?.to_string()) }
49+
unsafe { atoms::to_string2(self.context, &atom) }
5050
}
5151
pub fn is_enumerable(&self, index: u32) -> bool {
5252
if index >= self.length {

src/quickjsvalueadapter.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,6 @@ impl QuickJsValueAdapter {
398398
_ => unsafe { functions::call_to_string(self.context, self) },
399399
}
400400
}
401-
402-
pub fn to_str(&self) -> Result<&str, JsError> {
403-
if self.get_js_type() == JsValueType::String {
404-
unsafe { primitives::to_str(self.context, self) }
405-
} else {
406-
Err(JsError::new_str("this value is not a string"))
407-
}
408-
}
409401
}
410402

411403
#[cfg(test)]
@@ -424,7 +416,7 @@ pub mod tests {
424416
Ok(res) => {
425417
log::info!("script ran ok: {:?}", res);
426418
assert!(res.get_js_type() == JsValueType::String);
427-
assert_eq!(res.to_str().expect("str conv failed"), "hello world");
419+
assert_eq!(res.to_string().expect("str conv failed"), "hello world");
428420
}
429421
Err(e) => {
430422
log::error!("script failed: {}", e);

0 commit comments

Comments
 (0)