Skip to content

Commit 0b309d3

Browse files
0.8
1 parent fab20b5 commit 0b309d3

File tree

7 files changed

+116
-13
lines changed

7 files changed

+116
-13
lines changed

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
# 0.8 (WiP)
1+
# 0.9 (WiP)
22

3-
*
3+
# 0.8.0
4+
5+
* impld realm init hook
6+
* proxy info functions (see if obj is an instance of a proxy class)
47

58
# 0.7.2
69

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.7.2"
3+
version = "0.8.0"
44
authors = ["Andries Hiemstra <info@hirofa.com>"]
55
edition = "2018"
66
description = "Wrapper API and utils for the QuickJS JavaScript engine with support for Promise, Module, Async/await"
@@ -22,7 +22,7 @@ setimmediate = []
2222

2323

2424
[dependencies]
25-
hirofa_utils = "0.4"
25+
hirofa_utils = "0.5"
2626
#hirofa_utils = {path="../utils"}
2727
#hirofa_utils = {git="https://github.com/HiRoFa/utils"}
2828
backtrace = "0.3.56"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ Cargo.toml
8383

8484
```toml
8585
[dependencies]
86-
hirofa_utils = "0.4"
87-
quickjs_runtime = "0.7"
86+
hirofa_utils = "0.5"
87+
quickjs_runtime = "0.8"
8888
log = "0.4"
8989
simple-logging = "2.0"
9090
```

src/builder.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,30 @@ impl JsRuntimeBuilder for QuickJsRuntimeBuilder {
222222
self
223223
}
224224

225-
fn js_realm_adapter_init_hook<H: FnOnce(&<<Self as JsRuntimeBuilder>::JsRuntimeFacadeType as JsRuntimeFacade>::JsRuntimeAdapterType, &<<<Self as JsRuntimeBuilder>::JsRuntimeFacadeType as JsRuntimeFacade>::JsRuntimeAdapterType as JsRuntimeAdapter>::JsRealmAdapterType) -> Result<(), JsError> + Send + 'static>(self, _hook: H) -> Self{
226-
todo!()
225+
fn js_realm_adapter_init_hook<
226+
H: Fn(&QuickJsRuntimeAdapter, &QuickJsRealmAdapter) -> Result<(), JsError> + Send + 'static,
227+
>(
228+
self,
229+
hook: H,
230+
) -> Self {
231+
self.js_runtime_adapter_init_hook(move |rt| {
232+
rt.add_context_init_hook(hook)?;
233+
Ok(())
234+
})
227235
}
228236

229-
fn js_runtime_adapter_init_hook<H: FnOnce(&<<Self as JsRuntimeBuilder>::JsRuntimeFacadeType as JsRuntimeFacade>::JsRuntimeAdapterType) -> Result<(), JsError> + Send + 'static>(self, _hook: H) -> Self{
230-
todo!()
237+
fn js_runtime_adapter_init_hook<
238+
H: FnOnce(&QuickJsRuntimeAdapter) -> Result<(), JsError> + Send + 'static,
239+
>(
240+
self,
241+
hook: H,
242+
) -> Self {
243+
self.runtime_init_hook(|rt| {
244+
rt.exe_rt_task_in_event_loop(|rt| {
245+
let _ = hook(rt);
246+
});
247+
Ok(())
248+
})
231249
}
232250

233251
fn js_script_pre_processor<S: ScriptPreProcessor + Send + 'static>(

src/quickjsrealmadapter.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,22 @@ impl JsRealmAdapter for QuickJsRealmAdapter {
871871
let abuf = get_array_buffer_q(self, array)?;
872872
get_array_buffer_buffer_copy_q(self, &abuf)
873873
}
874+
875+
fn js_proxy_instance_get_info(
876+
&self,
877+
obj: &Self::JsValueAdapterType,
878+
) -> Result<(String, JsProxyInstanceId), JsError>
879+
where
880+
Self: Sized,
881+
{
882+
if let Some((p, i)) =
883+
crate::reflection::get_proxy_instance_proxy_and_instance_id_q(self, obj)
884+
{
885+
Ok((p.get_class_name(), i))
886+
} else {
887+
Err(JsError::new_str("not a proxy instance"))
888+
}
889+
}
874890
}
875891

876892
#[cfg(test)]

src/reflection/mod.rs

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,38 @@ impl Proxy {
542542
}
543543
}
544544

545+
pub fn get_proxy_instance_proxy_and_instance_id_q(
546+
q_ctx: &QuickJsRealmAdapter,
547+
obj: &JSValueRef,
548+
) -> Option<(Rc<Proxy>, usize)> {
549+
if !is_proxy_instance_q(q_ctx, obj) {
550+
None
551+
} else {
552+
let info = get_proxy_instance_info(obj.borrow_value());
553+
let cn = info.class_name.as_str();
554+
let registry = &*q_ctx.proxy_registry.borrow();
555+
if let Some(proxy) = registry.get(cn).cloned() {
556+
Some((proxy, info.id))
557+
} else {
558+
None
559+
}
560+
}
561+
}
562+
563+
pub fn is_proxy_instance_q(q_ctx: &QuickJsRealmAdapter, obj: &JSValueRef) -> bool {
564+
unsafe { is_proxy_instance(q_ctx.context, obj) }
565+
}
566+
567+
pub unsafe fn is_proxy_instance(ctx: *mut q::JSContext, obj: &JSValueRef) -> bool {
568+
if !obj.is_object() {
569+
false
570+
} else {
571+
let class_id = PROXY_INSTANCE_CLASS_ID.with(|rc| *rc.borrow());
572+
let proxy_class_proto: q::JSValue = q::JS_GetClassProto(ctx, class_id);
573+
q::JS_IsInstanceOf(ctx, *obj.borrow_value(), proxy_class_proto) != 0
574+
}
575+
}
576+
545577
pub fn new_instance2(
546578
proxy: &Proxy,
547579
q_ctx: &QuickJsRealmAdapter,
@@ -686,8 +718,8 @@ unsafe extern "C" fn constructor(
686718

687719
pub(crate) struct ProxyInstanceInfo {
688720
id: usize,
689-
class_name: String, // todo use unsafe to make these &str?
690-
context_id: String, // todo use unsafe to make these &str?
721+
class_name: String, // todo, store all proxies in an autoidmap with a usize as key and store proxy_class_id here instead of string
722+
context_id: String, // todo store all context ids in an autoidmap with a usize as key and store context_id here instead of string
691723
}
692724

693725
fn get_proxy_instance_info(val: &q::JSValue) -> &ProxyInstanceInfo {
@@ -1219,7 +1251,9 @@ unsafe extern "C" fn proxy_instance_set_prop(
12191251
pub mod tests {
12201252
use crate::facades::tests::init_test_rt;
12211253
use crate::quickjs_utils::{functions, primitives};
1222-
use crate::reflection::Proxy;
1254+
use crate::reflection::{
1255+
get_proxy_instance_proxy_and_instance_id_q, is_proxy_instance_q, Proxy,
1256+
};
12231257
use hirofa_utils::js_utils::JsError;
12241258
use hirofa_utils::js_utils::Script;
12251259
use log::trace;
@@ -1278,6 +1312,33 @@ pub mod tests {
12781312
assert!(err.contains("cant run"));
12791313
}
12801314

1315+
#[test]
1316+
pub fn test_proxy_instanceof() {
1317+
log::info!("> test_proxy_instanceof");
1318+
1319+
let rt = init_test_rt();
1320+
rt.exe_rt_task_in_event_loop(|q_js_rt| {
1321+
q_js_rt.gc();
1322+
let q_ctx = q_js_rt.get_main_context();
1323+
let _ = Proxy::new()
1324+
.constructor(|_q_ctx, _id, _args| Ok(()))
1325+
.namespace(vec!["com", "company"])
1326+
.name("Test")
1327+
.install(q_ctx, true);
1328+
let res = q_ctx
1329+
.eval(Script::new("test_tostring.es", "new com.company.Test()"))
1330+
.ok()
1331+
.expect("script failed");
1332+
assert!(is_proxy_instance_q(q_ctx, &res));
1333+
let info = get_proxy_instance_proxy_and_instance_id_q(q_ctx, &res)
1334+
.expect("could not get info");
1335+
let id = info.1;
1336+
let p = info.0;
1337+
println!("id={}", id);
1338+
assert_eq!(p.get_class_name().as_str(), "com.company.Test");
1339+
});
1340+
}
1341+
12811342
#[test]
12821343
pub fn test_to_string() {
12831344
log::info!("> test_proxy");

src/valueref.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::quickjs_utils::typedarrays::is_typed_array;
44
use crate::quickjs_utils::{arrays, errors, functions, primitives, promises};
55
use crate::quickjsruntimeadapter::QuickJsRuntimeAdapter;
6+
use crate::reflection::is_proxy_instance;
67
use hirofa_utils::js_utils::adapters::JsValueAdapter;
78
use hirofa_utils::js_utils::facades::JsValueType;
89
use hirofa_utils::js_utils::JsError;
@@ -298,6 +299,10 @@ impl JsValueAdapter for JSValueRef {
298299
unsafe { is_typed_array(self.context, self) }
299300
}
300301

302+
fn js_is_proxy_instance(&self) -> bool {
303+
unsafe { is_proxy_instance(self.context, self) }
304+
}
305+
301306
fn js_type_of(&self) -> &'static str {
302307
match self.get_tag() {
303308
TAG_BIG_INT => "bigint",

0 commit comments

Comments
 (0)