-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
call_raw and call_raw128 implemented!
- Loading branch information
Showing
9 changed files
with
223 additions
and
191 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,106 @@ | ||
// TODO basically copied into call_raw128 | ||
use std::convert::TryInto; | ||
|
||
use quickjs_wasm_rs::{to_qjs_value, CallbackArg, JSContextRef, JSValue, JSValueRef}; | ||
|
||
use crate::CONTEXT; | ||
|
||
pub fn native_function<'a>( | ||
context: &'a JSContextRef, | ||
_this: &CallbackArg, | ||
args: &[CallbackArg], | ||
) -> Result<JSValueRef<'a>, anyhow::Error> { | ||
let promise_id: String = args | ||
.get(0) | ||
.expect("call_raw promise_id argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let canister_id_bytes: Vec<u8> = args | ||
.get(1) | ||
.expect("call_raw canister_id_bytes is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let canister_id = candid::Principal::from_slice(&canister_id_bytes); | ||
let method: String = args | ||
.get(2) | ||
.expect("call_raw method argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let args_raw: Vec<u8> = args | ||
.get(3) | ||
.expect("call_raw args_raw argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let payment_candid_bytes: Vec<u8> = args | ||
.get(4) | ||
.expect("call_raw payment_candid_bytes argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let payment: u64 = candid::decode_one(&payment_candid_bytes)?; | ||
|
||
ic_cdk::spawn(async move { | ||
let call_result = | ||
ic_cdk::api::call::call_raw(canister_id, &method, &args_raw, payment).await; | ||
|
||
let (should_resolve, js_value) = match call_result { | ||
Ok(candid_bytes) => { | ||
let candid_bytes_js_value: JSValue = candid_bytes.into(); | ||
(true, candid_bytes_js_value) | ||
} | ||
Err(err) => { | ||
let err_js_value: JSValue = format!( | ||
"Rejection code {rejection_code}, {error_message}", | ||
rejection_code = (err.0 as i32).to_string(), | ||
error_message = err.1 | ||
) | ||
.into(); | ||
|
||
(false, err_js_value) | ||
} | ||
|
||
use wasmedge_quickjs::{AsObject, Context, JsFn, JsValue}; | ||
|
||
use crate::RUNTIME; | ||
|
||
pub struct NativeFunction; | ||
impl JsFn for NativeFunction { | ||
fn call(context: &mut Context, this_val: JsValue, argv: &[JsValue]) -> JsValue { | ||
let promise_id = if let JsValue::String(js_string) = argv.get(0).unwrap() { | ||
js_string.to_string() | ||
} else { | ||
panic!("conversion from JsValue to JsString failed") | ||
}; | ||
|
||
let canister_id_bytes = if let JsValue::ArrayBuffer(js_array_buffer) = argv.get(1).unwrap() | ||
{ | ||
js_array_buffer.to_vec() | ||
} else { | ||
panic!("conversion from JsValue to JsArrayBuffer failed") | ||
}; | ||
let canister_id = candid::Principal::from_slice(&canister_id_bytes); | ||
|
||
let method = if let JsValue::String(js_string) = argv.get(2).unwrap() { | ||
js_string.to_string() | ||
} else { | ||
panic!("conversion from JsValue to JsString failed") | ||
}; | ||
|
||
let args_raw = if let JsValue::ArrayBuffer(js_array_buffer) = argv.get(3).unwrap() { | ||
js_array_buffer.to_vec() | ||
} else { | ||
panic!("conversion from JsValue to JsArrayBuffer failed") | ||
}; | ||
|
||
let payment_string = if let JsValue::String(js_string) = argv.get(4).unwrap() { | ||
js_string.to_string() | ||
} else { | ||
panic!("conversion from JsValue to JsString failed") | ||
}; | ||
let payment: u64 = payment_string.parse().unwrap(); | ||
|
||
ic_cdk::spawn(async move { | ||
let call_result = | ||
ic_cdk::api::call::call_raw(canister_id, &method, &args_raw, payment).await; | ||
|
||
RUNTIME.with(|runtime| { | ||
let mut runtime = runtime.borrow_mut(); | ||
let runtime = runtime.as_mut().unwrap(); | ||
|
||
runtime.run_with_context(|context| { | ||
let global = context.get_global(); | ||
|
||
let (should_resolve, js_value) = match &call_result { | ||
Ok(candid_bytes) => { | ||
let candid_bytes_js_value: JsValue = | ||
context.new_array_buffer(candid_bytes).into(); | ||
|
||
(true, candid_bytes_js_value) | ||
} | ||
Err(err) => { | ||
let err_js_value: JsValue = context | ||
.new_error(&format!( | ||
"Rejection code {rejection_code}, {error_message}", | ||
rejection_code = (err.0 as i32).to_string(), | ||
error_message = err.1 | ||
)) | ||
.into(); | ||
|
||
(false, err_js_value) | ||
} | ||
}; | ||
|
||
if should_resolve { | ||
let resolve = global | ||
.get("_azleResolveIds") | ||
.to_obj() | ||
.unwrap() | ||
.get(format!("_resolve_{promise_id}").as_str()) | ||
.to_function() | ||
.unwrap(); | ||
|
||
resolve.call(&[js_value.clone()]); | ||
} else { | ||
let reject = global | ||
.get("_azleRejectIds") | ||
.to_obj() | ||
.unwrap() | ||
.get(format!("_reject_{promise_id}").as_str()) | ||
.to_function() | ||
.unwrap(); | ||
|
||
reject.call(&[js_value.clone()]); | ||
} | ||
|
||
CONTEXT.with(|context| { | ||
let mut context = context.borrow_mut(); | ||
let context = context.as_mut().unwrap(); | ||
|
||
let global = context.global_object().unwrap(); | ||
|
||
let js_value_ref = to_qjs_value(&context, &js_value).unwrap(); | ||
|
||
if should_resolve { | ||
let resolve = global | ||
.get_property("_azleResolveIds").unwrap() | ||
.get_property(format!("_resolve_{promise_id}").as_str()) | ||
.unwrap(); | ||
resolve.call(&resolve, &[js_value_ref]).unwrap(); | ||
} else { | ||
let reject = global | ||
.get_property("_azleRejectIds").unwrap() | ||
.get_property(format!("_reject_{promise_id}").as_str()) | ||
.unwrap(); | ||
reject.call(&reject, &[js_value_ref]).unwrap(); | ||
} | ||
|
||
context.execute_pending().unwrap(); | ||
// TODO do we need to progress setTimeouts and stuff? | ||
// TODO make sure to test this | ||
// context.event_loop().unwrap().run_tick_task(); | ||
context.promise_loop_poll(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
context.undefined_value() | ||
JsValue::UnDefined | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,89 +1,106 @@ | ||
// TODO basically copied from call_raw | ||
use std::convert::TryInto; | ||
|
||
use quickjs_wasm_rs::{to_qjs_value, CallbackArg, JSContextRef, JSValue, JSValueRef}; | ||
|
||
use crate::CONTEXT; | ||
|
||
pub fn native_function<'a>( | ||
context: &'a JSContextRef, | ||
_this: &CallbackArg, | ||
args: &[CallbackArg], | ||
) -> Result<JSValueRef<'a>, anyhow::Error> { | ||
let promise_id: String = args | ||
.get(0) | ||
.expect("call_raw promise_id argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let canister_id_bytes: Vec<u8> = args | ||
.get(1) | ||
.expect("call_raw canister_id_bytes is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let canister_id = candid::Principal::from_slice(&canister_id_bytes); | ||
let method: String = args | ||
.get(2) | ||
.expect("call_raw method argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let args_raw: Vec<u8> = args | ||
.get(3) | ||
.expect("call_raw args_raw argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let payment_candid_bytes: Vec<u8> = args | ||
.get(4) | ||
.expect("call_raw payment_candid_bytes argument is undefined") | ||
.to_js_value()? | ||
.try_into()?; | ||
let payment: u128 = candid::decode_one(&payment_candid_bytes)?; | ||
|
||
ic_cdk::spawn(async move { | ||
let call_result = | ||
ic_cdk::api::call::call_raw128(canister_id, &method, &args_raw, payment).await; | ||
|
||
let (should_resolve, js_value) = match call_result { | ||
Ok(candid_bytes) => { | ||
let candid_bytes_js_value: JSValue = candid_bytes.into(); | ||
(true, candid_bytes_js_value) | ||
} | ||
Err(err) => { | ||
let err_js_value: JSValue = format!( | ||
"Rejection code {rejection_code}, {error_message}", | ||
rejection_code = (err.0 as i32).to_string(), | ||
error_message = err.1 | ||
) | ||
.into(); | ||
|
||
(false, err_js_value) | ||
} | ||
|
||
use wasmedge_quickjs::{AsObject, Context, JsFn, JsValue}; | ||
|
||
use crate::RUNTIME; | ||
|
||
pub struct NativeFunction; | ||
impl JsFn for NativeFunction { | ||
fn call(context: &mut Context, this_val: JsValue, argv: &[JsValue]) -> JsValue { | ||
let promise_id = if let JsValue::String(js_string) = argv.get(0).unwrap() { | ||
js_string.to_string() | ||
} else { | ||
panic!("conversion from JsValue to JsString failed") | ||
}; | ||
|
||
let canister_id_bytes = if let JsValue::ArrayBuffer(js_array_buffer) = argv.get(1).unwrap() | ||
{ | ||
js_array_buffer.to_vec() | ||
} else { | ||
panic!("conversion from JsValue to JsArrayBuffer failed") | ||
}; | ||
let canister_id = candid::Principal::from_slice(&canister_id_bytes); | ||
|
||
let method = if let JsValue::String(js_string) = argv.get(2).unwrap() { | ||
js_string.to_string() | ||
} else { | ||
panic!("conversion from JsValue to JsString failed") | ||
}; | ||
|
||
let args_raw = if let JsValue::ArrayBuffer(js_array_buffer) = argv.get(3).unwrap() { | ||
js_array_buffer.to_vec() | ||
} else { | ||
panic!("conversion from JsValue to JsArrayBuffer failed") | ||
}; | ||
|
||
let payment_string = if let JsValue::String(js_string) = argv.get(4).unwrap() { | ||
js_string.to_string() | ||
} else { | ||
panic!("conversion from JsValue to JsString failed") | ||
}; | ||
let payment: u128 = payment_string.parse().unwrap(); | ||
|
||
ic_cdk::spawn(async move { | ||
let call_result = | ||
ic_cdk::api::call::call_raw128(canister_id, &method, &args_raw, payment).await; | ||
|
||
RUNTIME.with(|runtime| { | ||
let mut runtime = runtime.borrow_mut(); | ||
let runtime = runtime.as_mut().unwrap(); | ||
|
||
runtime.run_with_context(|context| { | ||
let global = context.get_global(); | ||
|
||
let (should_resolve, js_value) = match &call_result { | ||
Ok(candid_bytes) => { | ||
let candid_bytes_js_value: JsValue = | ||
context.new_array_buffer(candid_bytes).into(); | ||
|
||
(true, candid_bytes_js_value) | ||
} | ||
Err(err) => { | ||
let err_js_value: JsValue = context | ||
.new_error(&format!( | ||
"Rejection code {rejection_code}, {error_message}", | ||
rejection_code = (err.0 as i32).to_string(), | ||
error_message = err.1 | ||
)) | ||
.into(); | ||
|
||
(false, err_js_value) | ||
} | ||
}; | ||
|
||
if should_resolve { | ||
let resolve = global | ||
.get("_azleResolveIds") | ||
.to_obj() | ||
.unwrap() | ||
.get(format!("_resolve_{promise_id}").as_str()) | ||
.to_function() | ||
.unwrap(); | ||
|
||
resolve.call(&[js_value.clone()]); | ||
} else { | ||
let reject = global | ||
.get("_azleRejectIds") | ||
.to_obj() | ||
.unwrap() | ||
.get(format!("_reject_{promise_id}").as_str()) | ||
.to_function() | ||
.unwrap(); | ||
|
||
reject.call(&[js_value.clone()]); | ||
} | ||
|
||
CONTEXT.with(|context| { | ||
let mut context = context.borrow_mut(); | ||
let context = context.as_mut().unwrap(); | ||
|
||
let global = context.global_object().unwrap(); | ||
|
||
let js_value_ref = to_qjs_value(&context, &js_value).unwrap(); | ||
|
||
if should_resolve { | ||
let resolve = global | ||
.get_property("_azleResolveIds").unwrap() | ||
.get_property(format!("_resolve_{promise_id}").as_str()) | ||
.unwrap(); | ||
resolve.call(&resolve, &[js_value_ref]).unwrap(); | ||
} else { | ||
let reject = global | ||
.get_property("_azleRejectIds").unwrap() | ||
.get_property(format!("_reject_{promise_id}").as_str()) | ||
.unwrap(); | ||
reject.call(&reject, &[js_value_ref]).unwrap(); | ||
} | ||
|
||
context.execute_pending().unwrap(); | ||
// TODO do we need to progress setTimeouts and stuff? | ||
// TODO make sure to test this | ||
// context.event_loop().unwrap().run_tick_task(); | ||
context.promise_loop_poll(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
context.undefined_value() | ||
JsValue::UnDefined | ||
} | ||
} |
Oops, something went wrong.