quickjs_runtime/quickjs_utils/
mod.rs1use crate::quickjsruntimeadapter::QuickJsRuntimeAdapter;
4
5#[cfg(feature = "bellard")]
6pub mod class_ids {
7 pub const JS_CLASS_OBJECT: u32 = 1;
8 pub const JS_CLASS_ARRAY: u32 = 2;
9 pub const JS_CLASS_ERROR: u32 = 3;
10 pub const JS_CLASS_NUMBER: u32 = 4;
11 pub const JS_CLASS_STRING: u32 = 5;
12 pub const JS_CLASS_BOOLEAN: u32 = 6;
13 pub const JS_CLASS_SYMBOL: u32 = 7;
14 pub const JS_CLASS_ARGUMENTS: u32 = 8;
15 pub const JS_CLASS_MAPPED_ARGUMENTS: u32 = 9;
16 pub const JS_CLASS_DATE: u32 = 10;
17 pub const JS_CLASS_MODULE_NS: u32 = 11;
18 pub const JS_CLASS_C_FUNCTION: u32 = 12;
19 pub const JS_CLASS_BYTECODE_FUNCTION: u32 = 13;
20 pub const JS_CLASS_BOUND_FUNCTION: u32 = 14;
21 pub const JS_CLASS_C_FUNCTION_DATA: u32 = 15;
22 pub const JS_CLASS_GENERATOR_FUNCTION: u32 = 16;
23 pub const JS_CLASS_FOR_IN_ITERATOR: u32 = 17;
24 pub const JS_CLASS_REGEXP: u32 = 18;
25 pub const JS_CLASS_ARRAY_BUFFER: u32 = 19;
26 pub const JS_CLASS_SHARED_ARRAY_BUFFER: u32 = 20;
27 pub const JS_CLASS_UINT8C_ARRAY: u32 = 21;
28 pub const JS_CLASS_INT8_ARRAY: u32 = 22;
29 pub const JS_CLASS_UINT8_ARRAY: u32 = 23;
30 pub const JS_CLASS_INT16_ARRAY: u32 = 24;
31 pub const JS_CLASS_UINT16_ARRAY: u32 = 25;
32 pub const JS_CLASS_INT32_ARRAY: u32 = 26;
33 pub const JS_CLASS_UINT32_ARRAY: u32 = 27;
34 pub const JS_CLASS_BIG_INT64_ARRAY: u32 = 28;
35 pub const JS_CLASS_BIG_UINT64_ARRAY: u32 = 29;
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_ITERATOR: u32 = 39;
46 pub const JS_CLASS_ITERATOR_CONCAT: u32 = 40;
47 pub const JS_CLASS_ITERATOR_HELPER: u32 = 41;
48 pub const JS_CLASS_ITERATOR_WRAP: u32 = 42;
49 pub const JS_CLASS_MAP_ITERATOR: u32 = 43;
50 pub const JS_CLASS_SET_ITERATOR: u32 = 44;
51 pub const JS_CLASS_ARRAY_ITERATOR: u32 = 45;
52 pub const JS_CLASS_STRING_ITERATOR: u32 = 46;
53 pub const JS_CLASS_REGEXP_STRING_ITERATOR: u32 = 47;
54 pub const JS_CLASS_GENERATOR: u32 = 48;
55 pub const JS_CLASS_GLOBAL_OBJECT: u32 = 49;
56 pub const JS_CLASS_RAWJSON: u32 = 50;
57 pub const JS_CLASS_PROXY: u32 = 51;
58 pub const JS_CLASS_PROMISE: u32 = 52;
59 pub const JS_CLASS_PROMISE_RESOLVE_FUNCTION: u32 = 53;
60 pub const JS_CLASS_PROMISE_REJECT_FUNCTION: u32 = 54;
61 pub const JS_CLASS_ASYNC_FUNCTION: u32 = 55;
62 pub const JS_CLASS_ASYNC_FUNCTION_RESOLVE: u32 = 56;
63 pub const JS_CLASS_ASYNC_FUNCTION_REJECT: u32 = 57;
64 pub const JS_CLASS_ASYNC_FROM_SYNC_ITERATOR: u32 = 58;
65 pub const JS_CLASS_ASYNC_GENERATOR_FUNCTION: u32 = 59;
66 pub const JS_CLASS_ASYNC_GENERATOR: u32 = 60;
67 pub const JS_CLASS_WEAK_REF: u32 = 61;
68 pub const JS_CLASS_FINALIZATION_REGISTRY: u32 = 62;
69 pub const JS_CLASS_INIT_COUNT: u32 = 63;
70}
71#[cfg(feature = "quickjs-ng")]
72pub mod class_ids {
73 pub const JS_CLASS_OBJECT: u32 = 1;
74 pub const JS_CLASS_ARRAY: u32 = 2;
75 pub const JS_CLASS_ERROR: u32 = 3;
76 pub const JS_CLASS_NUMBER: u32 = 4;
77 pub const JS_CLASS_STRING: u32 = 5;
78 pub const JS_CLASS_BOOLEAN: u32 = 6;
79 pub const JS_CLASS_SYMBOL: u32 = 7;
80 pub const JS_CLASS_ARGUMENTS: u32 = 8;
81 pub const JS_CLASS_MAPPED_ARGUMENTS: u32 = 9;
82 pub const JS_CLASS_DATE: u32 = 10;
83 pub const JS_CLASS_MODULE_NS: u32 = 11;
84 pub const JS_CLASS_C_FUNCTION: u32 = 12;
85 pub const JS_CLASS_BYTECODE_FUNCTION: u32 = 13;
86 pub const JS_CLASS_BOUND_FUNCTION: u32 = 14;
87 pub const JS_CLASS_C_FUNCTION_DATA: u32 = 15;
88 pub const JS_CLASS_C_CLOSURE: u32 = 16;
89 pub const JS_CLASS_GENERATOR_FUNCTION: u32 = 17;
90 pub const JS_CLASS_FOR_IN_ITERATOR: u32 = 18;
91 pub const JS_CLASS_REGEXP: u32 = 19;
92 pub const JS_CLASS_ARRAY_BUFFER: u32 = 20;
93 pub const JS_CLASS_SHARED_ARRAY_BUFFER: u32 = 21;
94 pub const JS_CLASS_UINT8C_ARRAY: u32 = 22;
95 pub const JS_CLASS_INT8_ARRAY: u32 = 23;
96 pub const JS_CLASS_UINT8_ARRAY: u32 = 24;
97 pub const JS_CLASS_INT16_ARRAY: u32 = 25;
98 pub const JS_CLASS_UINT16_ARRAY: u32 = 26;
99 pub const JS_CLASS_INT32_ARRAY: u32 = 27;
100 pub const JS_CLASS_UINT32_ARRAY: u32 = 28;
101 pub const JS_CLASS_BIG_INT64_ARRAY: u32 = 29;
102 pub const JS_CLASS_BIG_UINT64_ARRAY: u32 = 30;
103 pub const JS_CLASS_FLOAT16_ARRAY: u32 = 31;
104 pub const JS_CLASS_FLOAT32_ARRAY: u32 = 32;
105 pub const JS_CLASS_FLOAT64_ARRAY: u32 = 33;
106 pub const JS_CLASS_DATAVIEW: u32 = 34;
107 pub const JS_CLASS_BIG_INT: u32 = 35;
108 pub const JS_CLASS_MAP: u32 = 36;
109 pub const JS_CLASS_SET: u32 = 37;
110 pub const JS_CLASS_WEAKMAP: u32 = 38;
111 pub const JS_CLASS_WEAKSET: u32 = 39;
112 pub const JS_CLASS_ITERATOR: u32 = 40;
113 pub const JS_CLASS_ITERATOR_CONCAT: u32 = 41;
114 pub const JS_CLASS_ITERATOR_HELPER: u32 = 42;
115 pub const JS_CLASS_ITERATOR_WRAP: u32 = 43;
116 pub const JS_CLASS_MAP_ITERATOR: u32 = 44;
117 pub const JS_CLASS_SET_ITERATOR: u32 = 45;
118 pub const JS_CLASS_ARRAY_ITERATOR: u32 = 46;
119 pub const JS_CLASS_STRING_ITERATOR: u32 = 47;
120 pub const JS_CLASS_REGEXP_STRING_ITERATOR: u32 = 48;
121 pub const JS_CLASS_GENERATOR: u32 = 49;
122 pub const JS_CLASS_PROXY: u32 = 50;
123 pub const JS_CLASS_PROMISE: u32 = 51;
124 pub const JS_CLASS_PROMISE_RESOLVE_FUNCTION: u32 = 52;
125 pub const JS_CLASS_PROMISE_REJECT_FUNCTION: u32 = 53;
126 pub const JS_CLASS_ASYNC_FUNCTION: u32 = 54;
127 pub const JS_CLASS_ASYNC_FUNCTION_RESOLVE: u32 = 55;
128 pub const JS_CLASS_ASYNC_FUNCTION_REJECT: u32 = 56;
129 pub const JS_CLASS_ASYNC_FROM_SYNC_ITERATOR: u32 = 57;
130 pub const JS_CLASS_ASYNC_GENERATOR_FUNCTION: u32 = 58;
131 pub const JS_CLASS_ASYNC_GENERATOR: u32 = 59;
132 pub const JS_CLASS_WEAK_REF: u32 = 60;
133 pub const JS_CLASS_FINALIZATION_REGISTRY: u32 = 61;
134 pub const JS_CLASS_DOM_EXCEPTION: u32 = 62;
135 pub const JS_CLASS_CALL_SITE: u32 = 63;
136 pub const JS_CLASS_INIT_COUNT: u32 = 64;
137}
138
139pub mod arrays;
140pub mod atoms;
141pub mod bigints;
142pub mod compile;
143pub mod dates;
144pub mod errors;
145pub mod functions;
146pub mod interrupthandler;
147pub mod iterators;
148pub mod json;
149pub mod maps;
150pub mod modules;
151pub mod objects;
152pub mod primitives;
153pub mod promises;
154pub mod properties;
155pub mod runtime;
156pub mod sets;
157pub mod typedarrays;
158
159use crate::jsutils::JsError;
160use crate::quickjs_utils::atoms::JSAtomRef;
161use crate::quickjs_utils::objects::get_property;
162use crate::quickjsrealmadapter::QuickJsRealmAdapter;
163use crate::quickjsvalueadapter::{QuickJsValueAdapter, TAG_NULL, TAG_UNDEFINED};
164use libquickjs_sys as q;
165
166pub fn gc(q_js_rt: &QuickJsRuntimeAdapter) {
172 log::trace!("GC called");
173 unsafe { q::JS_RunGC(q_js_rt.runtime) }
174 log::trace!("GC done");
175 }
177
178pub fn new_undefined_ref() -> QuickJsValueAdapter {
179 QuickJsValueAdapter::new_no_context(new_undefined(), "new_undefined_ref")
180}
181
182pub fn new_null() -> q::JSValue {
183 q::JSValue {
184 #[cfg(feature = "bellard")]
185 u: q::JSValueUnion { uint64: 0 },
186 #[cfg(feature = "quickjs-ng")]
187 u: q::JSValueUnion { int32: 0 },
188 tag: TAG_NULL,
189 }
190}
191
192pub fn new_undefined() -> q::JSValue {
193 q::JSValue {
194 #[cfg(feature = "bellard")]
195 u: q::JSValueUnion { uint64: 0 },
196 #[cfg(feature = "quickjs-ng")]
197 u: q::JSValueUnion { int32: 0 },
198 tag: TAG_UNDEFINED,
199 }
200}
201
202pub fn new_null_ref() -> QuickJsValueAdapter {
203 QuickJsValueAdapter::new_no_context(new_null(), "null_ref")
204}
205
206pub fn get_script_or_module_name_q(ctx: &QuickJsRealmAdapter) -> Result<String, JsError> {
208 unsafe { get_script_or_module_name(ctx.context) }
209}
210
211pub unsafe fn get_script_or_module_name(context: *mut q::JSContext) -> Result<String, JsError> {
215 for x in 0..100 {
216 let atom = q::JS_GetScriptOrModuleName(context, x);
217 let atom_ref = JSAtomRef::new(context, atom);
218 let r = atoms::to_string(context, &atom_ref)?;
219 if !r.is_empty() {
220 return Ok(r);
221 }
222 }
223 Ok("".to_string())
224}
225
226pub fn get_global_q(context: &QuickJsRealmAdapter) -> QuickJsValueAdapter {
227 unsafe { get_global(context.context) }
228}
229pub unsafe fn get_global(context: *mut q::JSContext) -> QuickJsValueAdapter {
232 let global = q::JS_GetGlobalObject(context);
233 QuickJsValueAdapter::new(context, global, false, true, "global")
234}
235pub unsafe fn get_constructor(
238 context: *mut q::JSContext,
239 constructor_name: &str,
240) -> Result<QuickJsValueAdapter, JsError> {
241 let global_ref = get_global(context);
242
243 let constructor_ref = get_property(context, &global_ref, constructor_name)?;
244
245 if constructor_ref.is_null_or_undefined() {
246 Err(JsError::new_string(format!(
247 "not found: {constructor_name}"
248 )))
249 } else {
250 Ok(constructor_ref)
251 }
252}
253pub unsafe fn get_memory_usage(runtime: *mut q::JSRuntime) -> q::JSMemoryUsage {
257 let mut mu = q::JSMemoryUsage {
258 malloc_size: 0,
259 malloc_limit: 0,
260 memory_used_size: 0,
261 malloc_count: 0,
262 memory_used_count: 0,
263 atom_count: 0,
264 atom_size: 0,
265 str_count: 0,
266 str_size: 0,
267 obj_count: 0,
268 obj_size: 0,
269 prop_count: 0,
270 prop_size: 0,
271 shape_count: 0,
272 shape_size: 0,
273 js_func_count: 0,
274 js_func_size: 0,
275 js_func_code_size: 0,
276 js_func_pc2line_count: 0,
277 js_func_pc2line_size: 0,
278 c_func_count: 0,
279 array_count: 0,
280 fast_array_count: 0,
281 fast_array_elements: 0,
282 binary_object_count: 0,
283 binary_object_size: 0,
284 };
285 q::JS_ComputeMemoryUsage(runtime, &mut mu);
286
287 mu
288}
289
290pub unsafe fn parse_args(
293 context: *mut q::JSContext,
294 argc: ::std::os::raw::c_int,
295 argv: *mut q::JSValue,
296) -> Vec<QuickJsValueAdapter> {
297 let arg_slice = std::slice::from_raw_parts(argv, argc as usize);
298 arg_slice
299 .iter()
300 .map(|raw| QuickJsValueAdapter::new(context, *raw, true, true, "quickjs_utils::parse_args"))
301 .collect::<Vec<_>>()
302}
303
304#[cfg(test)]
305pub mod tests {
306 use crate::facades::tests::init_test_rt;
307 use crate::jsutils::Script;
308 use crate::quickjs_utils::get_script_or_module_name_q;
309 use crate::values::JsValueConvertable;
310
311 #[test]
312 fn test_global() {
313 let rt = init_test_rt();
314 rt.exe_rt_task_in_event_loop(|q_js_rt| {
315 let _q_ctx = q_js_rt.get_main_realm();
316 });
317 }
318
319 #[test]
320 fn test_script_name() {
321 let rt = init_test_rt();
322 rt.set_function(&[], "testName", |q_ctx, _args| {
323 let res = get_script_or_module_name_q(q_ctx)?.to_js_value_facade();
324 Ok(res)
325 })
326 .ok()
327 .expect("func set failed");
328 let name_esvf = rt
329 .eval_sync(
330 None,
331 Script::new("the_name.es", "(function(){return(testName());}())"),
332 )
333 .ok()
334 .expect("script failed");
335 assert_eq!(name_esvf.get_str(), "the_name.es");
336 let name_esvf = rt
337 .eval_sync(
338 None,
339 Script::new("https://githubstuff.org/tes.js", "(testName())"),
340 )
341 .ok()
342 .expect("script failed");
343 assert_eq!(name_esvf.get_str(), "https://githubstuff.org/tes.js");
344 }
345}