From 7b216c93abf06b8d91d06951a62e7aecdd151f7b Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sat, 29 Jan 2022 20:47:55 +0000 Subject: [PATCH 1/7] frontend support for call_raw --- src/ir_def/arrange_ir.ml | 1 + src/ir_def/check_ir.ml | 8 ++++++++ src/ir_def/construct.ml | 8 ++++++++ src/ir_def/construct.mli | 1 + src/ir_def/ir.ml | 4 +++- src/ir_passes/async.ml | 17 +++++++++++++++++ src/prelude/prim.mo | 5 +++++ 7 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/ir_def/arrange_ir.ml b/src/ir_def/arrange_ir.ml index c6c42aff6f4..3e4b7e4bab1 100644 --- a/src/ir_def/arrange_ir.ml +++ b/src/ir_def/arrange_ir.ml @@ -98,6 +98,7 @@ and prim = function | ICRejectPrim -> Atom "ICRejectPrim" | ICCallerPrim -> Atom "ICCallerPrim" | ICCallPrim -> Atom "ICCallPrim" + | ICCallRawPrim -> Atom "ICCallRawPrim" | ICStableWrite t -> "ICStableWrite" $$ [typ t] | ICStableRead t -> "ICStableRead" $$ [typ t] diff --git a/src/ir_def/check_ir.ml b/src/ir_def/check_ir.ml index 70e31ef3e79..128487e7600 100644 --- a/src/ir_def/check_ir.ml +++ b/src/ir_def/check_ir.ml @@ -593,6 +593,14 @@ let rec check_exp env (exp:Ir.exp) : unit = error env exp1.at "expected function type, but expression produces type\n %s" (T.string_of_typ_expand t1) end + (* TODO: T.unit <: t ? *) + | ICCallRawPrim, [exp1; exp2; exp3; k; r] -> + typ exp1 <: T.principal; + typ exp2 <: T.text; + typ exp3 <: T.blob; + typ k <: T.Func (T.Local, T.Returns, [], [T.blob], []); + typ r <: T.Func (T.Local, T.Returns, [], [T.error], []); + T.unit <: t | ICStableRead t1, [] -> check_typ env t1; check (store_typ t1) "Invalid type argument to ICStableRead"; diff --git a/src/ir_def/construct.ml b/src/ir_def/construct.ml index 525d00d00ad..51616643535 100644 --- a/src/ir_def/construct.ml +++ b/src/ir_def/construct.ml @@ -176,6 +176,14 @@ let ic_callE f e k r = note = Note.{ def with typ = T.unit; eff = eff } } +let ic_call_rawE p m a k r = + let es = [p; m; a; k; r] in + let effs = List.map eff es in + let eff = List.fold_left max_eff T.Triv effs in + { it = PrimE (ICCallRawPrim, es); + at = no_region; + note = Note.{ def with typ = T.unit; eff = eff } + } (* tuples *) diff --git a/src/ir_def/construct.mli b/src/ir_def/construct.mli index 60d8bdb1000..c5e28f58444 100644 --- a/src/ir_def/construct.mli +++ b/src/ir_def/construct.mli @@ -56,6 +56,7 @@ val cps_awaitE : typ -> exp -> exp -> exp val ic_replyE : typ list -> exp -> exp val ic_rejectE : exp -> exp val ic_callE : exp -> exp -> exp -> exp -> exp +val ic_call_rawE : exp -> exp -> exp -> exp -> exp -> exp val projE : exp -> int -> exp val optE : exp -> exp val tagE : id -> exp -> exp diff --git a/src/ir_def/ir.ml b/src/ir_def/ir.ml index d1dfde217cf..c246fb091fb 100644 --- a/src/ir_def/ir.ml +++ b/src/ir_def/ir.ml @@ -162,6 +162,7 @@ and prim = | ICRejectPrim | ICCallerPrim | ICCallPrim + | ICCallRawPrim | ICStableWrite of Type.typ (* serialize value of stable type to stable memory *) | ICStableRead of Type.typ (* deserialize value of stable type from stable memory *) @@ -294,7 +295,8 @@ let map_prim t_typ t_id p = | ICReplyPrim ts -> ICReplyPrim (List.map t_typ ts) | ICRejectPrim | ICCallerPrim - | ICCallPrim -> p + | ICCallPrim + | ICCallRawPrim -> p | ICStableWrite t -> ICStableWrite (t_typ t) | ICStableRead t -> ICStableRead (t_typ t) diff --git a/src/ir_passes/async.ml b/src/ir_passes/async.ml index cc342fa04a2..0be3a04d02a 100644 --- a/src/ir_passes/async.ml +++ b/src/ir_passes/async.ml @@ -287,6 +287,23 @@ let transform mode prog = ) (varE nary_async)) .it + | PrimE (OtherPrim "call_raw", [exp1; exp2; exp3]) -> + let exp1' = t_exp exp1 in + let exp2' = t_exp exp2 in + let exp3' = t_exp exp3 in + let ((nary_async, nary_reply, reject), def) = new_nary_async_reply mode [T.blob] in + let _ = letEta in + (blockE ( + letP (tupP [varP nary_async; varP nary_reply; varP reject]) def :: + letEta exp1' (fun v1 -> + letEta exp2' (fun v2 -> + letEta exp3' (fun v3 -> + [ expD (ic_call_rawE v1 v2 v3 (varE nary_reply) (varE reject)) ] + ) + )) + ) + (varE nary_async)) + .it | PrimE (p, exps) -> PrimE (t_prim p, List.map t_exp exps) | BlockE b -> diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 899bd9037df..19bfd74cd14 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -357,3 +357,8 @@ func stableMemoryLoadBlob(offset : Nat64, size : Nat) : Blob = func stableMemoryStoreBlob(offset : Nat64, val : Blob) : () = (prim "stableMemoryStoreBlob" : (Nat64, Blob) -> ()) (offset, val); + +// raw calls +func call_raw(p : Principal, m : Text, a : Blob) : async Blob { + await (prim "call_raw" : (Principal, Text, Blob) -> async Blob) (p, m, a); +}; From 24888f7b59a4c60135f6b5f68eeaa2a1b7942efb Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sat, 29 Jan 2022 21:17:42 +0000 Subject: [PATCH 2/7] implement simple test --- test/run-drun/call-raw.mo | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 test/run-drun/call-raw.mo diff --git a/test/run-drun/call-raw.mo b/test/run-drun/call-raw.mo new file mode 100644 index 00000000000..f3c49bd6513 --- /dev/null +++ b/test/run-drun/call-raw.mo @@ -0,0 +1,18 @@ +import P "mo:⛔"; + +actor self { + + public shared func test() : async () {}; + + public shared func go() { + let blob = await P.call_raw(P.principalOfActor(self),"test", "\44\49\44\4C\00\00"); + assert (blob == ("\44\49\44\4C\00\00": Blob)); + } + +}; + +//SKIP run +//SKIP run-low +//SKIP run-ir +//CALL ingress go 0x4449444C0000 +//CALL ingress go 0x4449444C0000 From 9d2b49b8ff359bffe24cd3e1399ecf68282b763f Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sat, 29 Jan 2022 22:21:07 +0000 Subject: [PATCH 3/7] backend; needs fixing --- src/codegen/compile.ml | 53 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 41a7735007e..94a579e3638 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -6362,8 +6362,22 @@ module FuncDec = struct deserialization); the reject callback function is unique. *) - let closures_to_reply_reject_callbacks env ts = - let reply_name = "@callback<" ^ Typ_hash.typ_hash (Type.Tup ts) ^ ">" in + let closures_to_reply_reject_callbacks_aux env ts_opt = + let arity, reply_name, from_arg_data = + match ts_opt with + | Some ts -> + (List.length ts, + "@callback<" ^ Typ_hash.typ_hash (Type.Tup ts) ^ ">", + fun env -> Serialization.deserialize env ts) + | None -> + (1, + "@callback", + (fun env -> + Blob.of_size_copy env + (fun env -> IC.system_call env "ic0" "msg_arg_data_size") + (fun env -> IC.system_call env "ic0" "msg_arg_data_copy") + (fun env -> compile_unboxed_const 0l))) + in Func.define_built_in env reply_name ["env", I32Type] [] (fun env -> message_start env (Type.Shared Type.Write) ^^ (* Look up continuation *) @@ -6374,11 +6388,11 @@ module FuncDec = struct set_closure ^^ get_closure ^^ - (* Deserialize reply arguments *) - Serialization.deserialize env ts ^^ + (* Deserialize/Blobify reply arguments *) + from_arg_data env ^^ get_closure ^^ - Closure.call_closure env (List.length ts) 0 ^^ + Closure.call_closure env arity 0 ^^ message_cleanup env (Type.Shared Type.Write) ); @@ -6418,6 +6432,11 @@ module FuncDec = struct compile_unboxed_const (E.add_fun_ptr env (E.built_in env reject_name)) ^^ get_cb_index + let closures_to_reply_reject_callbacks env ts = + closures_to_reply_reject_callbacks_aux env (Some ts) + let closures_to_raw_reply_reject_callbacks env = + closures_to_reply_reject_callbacks_aux env None + let ignoring_callback env = (* for one-way calls, we use an invalid table entry as the callback. this way, the callback, when it comes back, will (safely) trap, even if the @@ -6470,6 +6489,14 @@ module FuncDec = struct (closures_to_reply_reject_callbacks env ts2 [get_k; get_r]) (fun _ -> get_arg ^^ Serialization.serialize env ts1) + let ic_call_raw env get_meth_pair get_arg get_k get_r = + ic_call_threaded + env + "raw call" + get_meth_pair + (closures_to_raw_reply_reject_callbacks env [get_k; get_r]) + (fun _ -> get_arg) + let ic_self_call env ts get_meth_pair get_future get_k get_r = ic_call_threaded env @@ -8234,7 +8261,21 @@ and compile_exp (env : E.t) ae exp = compile_exp_vanilla env ae r ^^ set_r ^^ FuncDec.ic_call env ts1 ts2 get_meth_pair get_arg get_k get_r add_cycles end - + | ICCallRawPrim, [p;m;a;k;r] -> + SR.unit, begin + let (set_meth_pair, get_meth_pair) = new_local env "meth_pair" in + let (set_arg, get_arg) = new_local env "arg" in + let (set_k, get_k) = new_local env "k" in + let (set_r, get_r) = new_local env "r" in + let add_cycles = Internals.add_cycles env ae in + compile_exp_vanilla env ae p ^^ + compile_exp_vanilla env ae m ^^ + Tuple.from_stack env 2 ^^ set_meth_pair ^^ + compile_exp_vanilla env ae a ^^ set_arg ^^ + compile_exp_vanilla env ae k ^^ set_k ^^ + compile_exp_vanilla env ae r ^^ set_r ^^ + FuncDec.ic_call_raw env get_meth_pair get_arg get_k get_r add_cycles + end | ICStableRead ty, [] -> (* * On initial install: From f179358a311681d0a10ed07757d15b49158a7cfa Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sun, 30 Jan 2022 00:17:49 +0000 Subject: [PATCH 4/7] extend call-raw.mo test --- src/codegen/compile.ml | 2 +- test/run-drun/call-raw.mo | 93 +++++++++++++++++++++++-- test/run-drun/ok/call-raw.drun-run.ok | 13 ++++ test/run-drun/ok/call-raw.ic-ref-run.ok | 20 ++++++ 4 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 test/run-drun/ok/call-raw.drun-run.ok create mode 100644 test/run-drun/ok/call-raw.ic-ref-run.ok diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 94a579e3638..20a686d5ee2 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -6495,7 +6495,7 @@ module FuncDec = struct "raw call" get_meth_pair (closures_to_raw_reply_reject_callbacks env [get_k; get_r]) - (fun _ -> get_arg) + (fun _ -> get_arg ^^ Blob.as_ptr_len env) let ic_self_call env ts get_meth_pair get_future get_k get_r = ic_call_threaded diff --git a/test/run-drun/call-raw.mo b/test/run-drun/call-raw.mo index f3c49bd6513..855e3173baf 100644 --- a/test/run-drun/call-raw.mo +++ b/test/run-drun/call-raw.mo @@ -2,17 +2,98 @@ import P "mo:⛔"; actor self { - public shared func test() : async () {}; - public shared func go() { - let blob = await P.call_raw(P.principalOfActor(self),"test", "\44\49\44\4C\00\00"); - assert (blob == ("\44\49\44\4C\00\00": Blob)); - } + public shared func sint() : async Int { + return 2; + }; + + public shared func snat() : async Nat { + return 2; + }; + + public shared func stext() : async Text { + return "hello"; + }; + + public shared func stuple() : async (Nat, Bool, Char) { + return (1, true, 'a'); + }; + + public shared func unit() : async () { + P.debugPrint("unit!"); + }; + + public shared func int(n : Int) : async Int { + P.debugPrint(debug_show("int",n)); + return n; + }; + + public shared func text(t : Text) : async Text { + P.debugPrint(debug_show("text", t)); + return t; + }; + + public shared func tuple(n: Nat, b: Bool, c: Char) : async (Nat, Bool, Char) { + P.debugPrint(debug_show("text", (n, b, c))); + return (n, b, c); + }; + + public shared func trapInt(n : Int) : async Int { + P.trap("ohoh"); + }; + public shared func go() : async () { + let p = P.principalOfActor(self); + + do { + let arg : Blob = "DIDL\00\00"; + let res = await P.call_raw(p,"unit", arg); + assert (res == arg); + }; + + do { + let arg : Blob = "DIDL\00\01\7c\01"; + let res = await P.call_raw(p,"int", arg); + assert (res == arg); + }; + + do { + let arg : Blob = "DIDL\00\01\7c\02"; + let res = await P.call_raw(p,"int", arg); + assert (res == arg); + }; + + do { + let arg : Blob = "DIDL\00\01\71\05\68\65\6c\6c\6f"; + let res = await P.call_raw(p,"text", arg); + assert (res == arg); + }; + + do { + let arg : Blob = "DIDL\00\03\7d\7e\79\01\01\61\00\00\00"; + let res = await P.call_raw(p,"tuple", arg); + assert (res == arg); + }; + + do { + let arg : Blob = "DIDL\00\01\7c\01"; + try { + let res = await P.call_raw(p,"trapInt", arg); + assert false; + } + catch e { + P.debugPrint(P.errorMessage(e)); + } + }; + } }; //SKIP run //SKIP run-low //SKIP run-ir +//CALL ingress sint 0x4449444C0000 +//CALL ingress snat 0x4449444C0000 +//CALL ingress stext 0x4449444C0000 +//CALL ingress stuple 0x4449444C0000 //CALL ingress go 0x4449444C0000 -//CALL ingress go 0x4449444C0000 + diff --git a/test/run-drun/ok/call-raw.drun-run.ok b/test/run-drun/ok/call-raw.drun-run.ok new file mode 100644 index 00000000000..646a7333116 --- /dev/null +++ b/test/run-drun/ok/call-raw.drun-run.ok @@ -0,0 +1,13 @@ +ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 +ingress Completed: Reply: 0x4449444c0000 +ingress Completed: Reply: 0x4449444c00017c02 +ingress Completed: Reply: 0x4449444c00017d02 +ingress Completed: Reply: 0x4449444c0001710568656c6c6f +ingress Completed: Reply: 0x4449444c00037d7e79010161000000 +debug.print: unit! +debug.print: ("int", +1) +debug.print: ("int", +2) +debug.print: ("text", "hello") +debug.print: ("text", (1, true, 'a')) +debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: ohoh +ingress Completed: Reply: 0x4449444c0000 diff --git a/test/run-drun/ok/call-raw.ic-ref-run.ok b/test/run-drun/ok/call-raw.ic-ref-run.ok new file mode 100644 index 00000000000..104565ada2c --- /dev/null +++ b/test/run-drun/ok/call-raw.ic-ref-run.ok @@ -0,0 +1,20 @@ +→ update create_canister(record {settings = null}) +← replied: (record {hymijyo = principal "cvccv-qqaaq-aaaaa-aaaaa-c"}) +→ update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0… +← replied: () +→ update sint() +← replied: (+2) +→ update snat() +← replied: (2) +→ update stext() +← replied: ("hello") +→ update stuple() +← replied: (1, true, (97 : nat32)) +→ update go() +debug.print: unit! +debug.print: ("int", +1) +debug.print: ("int", +2) +debug.print: ("text", "hello") +debug.print: ("text", (1, true, 'a')) +debug.print: canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: ohoh" +← replied: () From 52db92759300d8e3b8a4d6623934ab351f946688 Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sun, 30 Jan 2022 00:42:46 +0000 Subject: [PATCH 5/7] move call_raw to internals to avoid wasi type-checking error in Prim --- src/prelude/internals.mo | 5 +++++ src/prelude/prim.mo | 5 +---- test/fail/ok/illegal-await.tc.ok | 10 +++++----- test/run-drun/call-raw.mo | 1 - 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/prelude/internals.mo b/src/prelude/internals.mo index 7a719e526aa..8a4048fa142 100644 --- a/src/prelude/internals.mo +++ b/src/prelude/internals.mo @@ -406,3 +406,8 @@ func @create_actor_helper(wasm_module_ : Blob, arg_ : Blob) : async Principal = }); return canister_id_; }; + +// raw calls +func @call_raw(p : Principal, m : Text, a : Blob) : async Blob { + await (prim "call_raw" : (Principal, Text, Blob) -> async Blob) (p, m, a); +}; diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 19bfd74cd14..c3cdbde92ca 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -358,7 +358,4 @@ func stableMemoryLoadBlob(offset : Nat64, size : Nat) : Blob = func stableMemoryStoreBlob(offset : Nat64, val : Blob) : () = (prim "stableMemoryStoreBlob" : (Nat64, Blob) -> ()) (offset, val); -// raw calls -func call_raw(p : Principal, m : Text, a : Blob) : async Blob { - await (prim "call_raw" : (Principal, Text, Blob) -> async Blob) (p, m, a); -}; +let call_raw = @call_raw; \ No newline at end of file diff --git a/test/fail/ok/illegal-await.tc.ok b/test/fail/ok/illegal-await.tc.ok index 0877fcb8a64..76b9f9fc8cb 100644 --- a/test/fail/ok/illegal-await.tc.ok +++ b/test/fail/ok/illegal-await.tc.ok @@ -24,14 +24,14 @@ illegal-await.mo:24.11: info, start of scope $anon-async-24.11 mentioned in erro illegal-await.mo:26.5: info, end of scope $anon-async-24.11 mentioned in error at illegal-await.mo:25.7-25.14 illegal-await.mo:22.10: info, start of scope $anon-async-22.10 mentioned in error at illegal-await.mo:25.7-25.14 illegal-await.mo:27.3: info, end of scope $anon-async-22.10 mentioned in error at illegal-await.mo:25.7-25.14 -illegal-await.mo:35.11-35.12: type error [M0087], ill-scoped await: expected async type from current scope $Rec, found async type from other scope $/3 +illegal-await.mo:35.11-35.12: type error [M0087], ill-scoped await: expected async type from current scope $Rec, found async type from other scope $/5 scope $Rec is illegal-await.mo:33.44-40.2 - scope $/3 is illegal-await.mo:33.1-40.2 + scope $/5 is illegal-await.mo:33.1-40.2 illegal-await.mo:33.44: info, start of scope $Rec mentioned in error at illegal-await.mo:35.5-35.12 illegal-await.mo:40.1: info, end of scope $Rec mentioned in error at illegal-await.mo:35.5-35.12 -illegal-await.mo:33.1: info, start of scope $/3 mentioned in error at illegal-await.mo:35.5-35.12 -illegal-await.mo:40.1: info, end of scope $/3 mentioned in error at illegal-await.mo:35.5-35.12 +illegal-await.mo:33.1: info, start of scope $/5 mentioned in error at illegal-await.mo:35.5-35.12 +illegal-await.mo:40.1: info, end of scope $/5 mentioned in error at illegal-await.mo:35.5-35.12 illegal-await.mo:38.20-38.21: type error [M0096], expression of type - async<$/3> () + async<$/5> () cannot produce expected type async<$Rec> () diff --git a/test/run-drun/call-raw.mo b/test/run-drun/call-raw.mo index 855e3173baf..18ca52e1504 100644 --- a/test/run-drun/call-raw.mo +++ b/test/run-drun/call-raw.mo @@ -2,7 +2,6 @@ import P "mo:⛔"; actor self { - public shared func sint() : async Int { return 2; }; From 32ed8ee8f7c583efdf653f0d470a189106517396 Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sun, 30 Jan 2022 10:39:16 +0000 Subject: [PATCH 6/7] Update src/prelude/prim.mo --- src/prelude/prim.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index c3cdbde92ca..db01dd58b45 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -358,4 +358,4 @@ func stableMemoryLoadBlob(offset : Nat64, size : Nat) : Blob = func stableMemoryStoreBlob(offset : Nat64, val : Blob) : () = (prim "stableMemoryStoreBlob" : (Nat64, Blob) -> ()) (offset, val); -let call_raw = @call_raw; \ No newline at end of file +let call_raw = @call_raw; From 87fe52aa4e20722531c12c314164b8f790d9a07d Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Sun, 30 Jan 2022 18:14:57 +0000 Subject: [PATCH 7/7] convert method Text to Blob, normalizing rope, for ic_call_raw --- src/codegen/compile.ml | 2 +- test/run-drun/call-raw.mo | 12 ++++++++++++ test/run-drun/ok/call-raw.drun-run.ok | 1 + test/run-drun/ok/call-raw.ic-ref-run.ok | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 20a686d5ee2..8f9e94190fd 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -8269,7 +8269,7 @@ and compile_exp (env : E.t) ae exp = let (set_r, get_r) = new_local env "r" in let add_cycles = Internals.add_cycles env ae in compile_exp_vanilla env ae p ^^ - compile_exp_vanilla env ae m ^^ + compile_exp_vanilla env ae m ^^ Text.to_blob env ^^ Tuple.from_stack env 2 ^^ set_meth_pair ^^ compile_exp_vanilla env ae a ^^ set_arg ^^ compile_exp_vanilla env ae k ^^ set_k ^^ diff --git a/test/run-drun/call-raw.mo b/test/run-drun/call-raw.mo index 18ca52e1504..c4bf3c19f08 100644 --- a/test/run-drun/call-raw.mo +++ b/test/run-drun/call-raw.mo @@ -41,6 +41,10 @@ actor self { P.trap("ohoh"); }; + public shared func supercalifragilisticexpialidocious() : async () { + P.debugPrint("supercalifragilisticexpialidocious"); + }; + public shared func go() : async () { let p = P.principalOfActor(self); @@ -84,6 +88,14 @@ actor self { P.debugPrint(P.errorMessage(e)); } }; + + do { + let m = "super"#"cali"#"fragilisticexpialidocious"; + let arg : Blob = "DIDL\00\00"; + let res = await P.call_raw(p, m, arg); + assert (res == arg); + }; + } }; diff --git a/test/run-drun/ok/call-raw.drun-run.ok b/test/run-drun/ok/call-raw.drun-run.ok index 646a7333116..13c391738f9 100644 --- a/test/run-drun/ok/call-raw.drun-run.ok +++ b/test/run-drun/ok/call-raw.drun-run.ok @@ -10,4 +10,5 @@ debug.print: ("int", +2) debug.print: ("text", "hello") debug.print: ("text", (1, true, 'a')) debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: ohoh +debug.print: supercalifragilisticexpialidocious ingress Completed: Reply: 0x4449444c0000 diff --git a/test/run-drun/ok/call-raw.ic-ref-run.ok b/test/run-drun/ok/call-raw.ic-ref-run.ok index 104565ada2c..cc96aa77d01 100644 --- a/test/run-drun/ok/call-raw.ic-ref-run.ok +++ b/test/run-drun/ok/call-raw.ic-ref-run.ok @@ -17,4 +17,5 @@ debug.print: ("int", +2) debug.print: ("text", "hello") debug.print: ("text", (1, true, 'a')) debug.print: canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: ohoh" +debug.print: supercalifragilisticexpialidocious ← replied: ()