From c10b8fef1b7adaa97154ae545cc69f9fd23c8c7b Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 26 Jun 2024 19:34:06 -0600 Subject: [PATCH 01/30] Add 'Prim.componentCall()' for interacting with an external Wasm component --- src/codegen/compile.ml | 8 ++++++++ src/prelude/prim.mo | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index bbce0ee1646..e9acf6bd0c6 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11252,6 +11252,11 @@ and compile_prim_invocation (env : E.t) ae p es at = compile_exp_as env ae SR.UnboxedFloat64 e ^^ E.call_import env "rts" "log" (* musl *) + | OtherPrim "componentCall", [e] -> + SR.UnboxedWord32 Type.Nat32, + compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ + E.call_import env "component" "call" + (* Other prims, nullary *) | SystemTimePrim, [] -> @@ -12818,6 +12823,9 @@ let compile mode rts (prog : Ir.prog) : Wasm_exts.CustomModule.extended_module = IC.system_imports env; RTS.system_imports env; + (* Component model *) + E.add_func_import env "component" "call" [I32Type] [I32Type]; + compile_init_func env prog; let start_fi_o = match E.mode env with | Flags.ICMode | Flags.RefMode -> diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 27e2efa3783..45331d82d99 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -267,6 +267,8 @@ func arctan2(y : Float, x : Float) : Float = (prim "fatan2" : (Float, Float) -> func exp(f : Float) : Float = (prim "fexp" : Float -> Float) f; func log(f : Float) : Float = (prim "flog" : Float -> Float) f; +func componentCall(n : Nat32) : Nat32 = (prim "componentCall" : Nat32 -> Nat32) n; + // Array utilities func Array_init(len : Nat, x : T) : [var T] { From fe8b7f44f27dbff04b9dd331c825123dab901198 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 26 Jun 2024 19:57:09 -0600 Subject: [PATCH 02/30] Add '-import-component' flag --- src/codegen/compile.ml | 5 +++-- src/exes/moc.ml | 3 +++ src/mo_config/flags.ml | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index e9acf6bd0c6..a5edd3630c3 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11252,7 +11252,7 @@ and compile_prim_invocation (env : E.t) ae p es at = compile_exp_as env ae SR.UnboxedFloat64 e ^^ E.call_import env "rts" "log" (* musl *) - | OtherPrim "componentCall", [e] -> + | OtherPrim "componentCall", [e] when !Flags.import_component -> SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ E.call_import env "component" "call" @@ -12824,7 +12824,8 @@ let compile mode rts (prog : Ir.prog) : Wasm_exts.CustomModule.extended_module = RTS.system_imports env; (* Component model *) - E.add_func_import env "component" "call" [I32Type] [I32Type]; + if !Flags.import_component then + E.add_func_import env "component" "call" [I32Type] [I32Type]; compile_init_func env prog; let start_fi_o = match E.mode env with diff --git a/src/exes/moc.ml b/src/exes/moc.ml index 630778afd54..369ee1f80cd 100644 --- a/src/exes/moc.ml +++ b/src/exes/moc.ml @@ -109,6 +109,9 @@ let argspec = [ "-wasi-system-api", Arg.Unit (fun () -> Flags.(compile_mode := WASIMode)), " use the WASI system API (wasmtime)"; + "-import-component", + Arg.Unit (fun () -> Flags.(import_component := true)), + " enable calling an external Wasm component"; "-ref-system-api", Arg.Unit (fun () -> Flags.(compile_mode := RefMode)), " use the reference implementation of the Internet Computer system API (ic-ref-run)"; diff --git a/src/mo_config/flags.ml b/src/mo_config/flags.ml index 849dd30e7a0..033fbfbc0fe 100644 --- a/src/mo_config/flags.ml +++ b/src/mo_config/flags.ml @@ -50,3 +50,4 @@ let rtti = ref false let trap_on_call_error = ref false let use_stable_regions = ref false let share_code = ref false +let import_component = ref false From 163fb60237764e9b88f34a637ab1dd74da5a4aec Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 10:28:40 -0600 Subject: [PATCH 03/30] Add M0200 error message ('component import is unavailable') --- src/codegen/compile.ml | 16 +++++++++++----- src/lang_utils/error_codes.ml | 1 + src/lang_utils/error_codes/M0200.md | 5 +++++ src/prelude/prim.mo | 2 ++ 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 src/lang_utils/error_codes/M0200.md diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index a5edd3630c3..9450410c165 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11252,10 +11252,16 @@ and compile_prim_invocation (env : E.t) ae p es at = compile_exp_as env ae SR.UnboxedFloat64 e ^^ E.call_import env "rts" "log" (* musl *) - | OtherPrim "componentCall", [e] when !Flags.import_component -> - SR.UnboxedWord32 Type.Nat32, - compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ - E.call_import env "component" "call" + | OtherPrim "componentCall", [e] -> + if !Flags.import_component then + SR.UnboxedWord32 Type.Nat32, + compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ + E.call_import env "component" "call" + else + (* TODO: type checking error? *) + Printf.printf "%s" (Diag.string_of_message ( + Diag.error_message at "M0199" "RTS" (Printf.sprintf "component import is unavailable" s'))); + exit 1) (* Other prims, nullary *) @@ -12823,7 +12829,7 @@ let compile mode rts (prog : Ir.prog) : Wasm_exts.CustomModule.extended_module = IC.system_imports env; RTS.system_imports env; - (* Component model *) + (* Wasm component model *) if !Flags.import_component then E.add_func_import env "component" "call" [I32Type] [I32Type]; diff --git a/src/lang_utils/error_codes.ml b/src/lang_utils/error_codes.ml index 15158cb264a..9d78667952b 100644 --- a/src/lang_utils/error_codes.ml +++ b/src/lang_utils/error_codes.ml @@ -203,4 +203,5 @@ let error_codes : (string * string option) list = "M0197", Some([%blob "lang_utils/error_codes/M0197.md"]); (* `system` capability required *) "M0198", Some([%blob "lang_utils/error_codes/M0198.md"]); (* Unused field pattern warning *) "M0199", Some([%blob "lang_utils/error_codes/M0199.md"]); (* Deprecate experimental stable memory *) + "M0200", Some([%blob "lang_utils/error_codes/M0200.md"]); (* Component import is unavailable *) ] diff --git a/src/lang_utils/error_codes/M0200.md b/src/lang_utils/error_codes/M0200.md new file mode 100644 index 00000000000..09e040ac8f3 --- /dev/null +++ b/src/lang_utils/error_codes/M0200.md @@ -0,0 +1,5 @@ +# M0200 + +This error indicates that the Wasm component model (cross-language) functionality is not enabled. + +You can fix this by passing the `-import-component` compiler flag, e.g. `moc -wasi-system-api -import-component ...`. diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index b03cf339491..cd9e11e853b 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -267,6 +267,8 @@ func arctan2(y : Float, x : Float) : Float = (prim "fatan2" : (Float, Float) -> func exp(f : Float) : Float = (prim "fexp" : Float -> Float) f; func log(f : Float) : Float = (prim "flog" : Float -> Float) f; +// Wasm component model functions + func componentCall(n : Nat32) : Nat32 = (prim "componentCall" : Nat32 -> Nat32) n; // Array utilities From 8c113053baf96853047d8a056977447fa7836b06 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 10:39:28 -0600 Subject: [PATCH 04/30] Fix compile error --- src/codegen/compile.ml | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 9450410c165..e624580ad9d 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11253,15 +11253,13 @@ and compile_prim_invocation (env : E.t) ae p es at = E.call_import env "rts" "log" (* musl *) | OtherPrim "componentCall", [e] -> - if !Flags.import_component then - SR.UnboxedWord32 Type.Nat32, - compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ - E.call_import env "component" "call" - else - (* TODO: type checking error? *) + if not !Flags.import_component then ( Printf.printf "%s" (Diag.string_of_message ( - Diag.error_message at "M0199" "RTS" (Printf.sprintf "component import is unavailable" s'))); - exit 1) + Diag.error_message at "M0199" "RTS" (Printf.sprintf "component import is unavailable"))); + exit 1); + SR.UnboxedWord32 Type.Nat32, + compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ + E.call_import env "component" "call" (* Other prims, nullary *) From d729cd59e1692ecd894ea7d32adca18cfd08e76b Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 11:28:12 -0600 Subject: [PATCH 05/30] Add test --- src/codegen/compile.ml | 2 +- test/fail/import-component.mo | 5 +++++ test/fail/ok/import-component.tc.ok | 1 + test/fail/ok/import-component.tc.ret.ok | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test/fail/import-component.mo create mode 100644 test/fail/ok/import-component.tc.ok create mode 100644 test/fail/ok/import-component.tc.ret.ok diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index e624580ad9d..c2b47fba3ca 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11255,7 +11255,7 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "componentCall", [e] -> if not !Flags.import_component then ( Printf.printf "%s" (Diag.string_of_message ( - Diag.error_message at "M0199" "RTS" (Printf.sprintf "component import is unavailable"))); + Diag.error_message at "M0199" "RTS" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); exit 1); SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ diff --git a/test/fail/import-component.mo b/test/fail/import-component.mo new file mode 100644 index 00000000000..64ef04e7b0f --- /dev/null +++ b/test/fail/import-component.mo @@ -0,0 +1,5 @@ +import P = "mo:⛔"; + +ignore P.callComponent(123); + +assert false; diff --git a/test/fail/ok/import-component.tc.ok b/test/fail/ok/import-component.tc.ok new file mode 100644 index 00000000000..d0dbac1113e --- /dev/null +++ b/test/fail/ok/import-component.tc.ok @@ -0,0 +1 @@ +import-component.mo:3.8-3.28: RTS error [M0199], component import is unavailable (pass `-import-component` flag) diff --git a/test/fail/ok/import-component.tc.ret.ok b/test/fail/ok/import-component.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/import-component.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 From 36b92cf16af6abc550bdb92319322e7d71cc8219 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 11:32:53 -0600 Subject: [PATCH 06/30] Adjust error code in error message --- src/codegen/compile.ml | 2 +- test/fail/ok/import-component.tc.ok | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index c2b47fba3ca..30b42b4cd91 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11255,7 +11255,7 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "componentCall", [e] -> if not !Flags.import_component then ( Printf.printf "%s" (Diag.string_of_message ( - Diag.error_message at "M0199" "RTS" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); + Diag.error_message at "M0200" "RTS" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); exit 1); SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ diff --git a/test/fail/ok/import-component.tc.ok b/test/fail/ok/import-component.tc.ok index d0dbac1113e..c82dcd1af14 100644 --- a/test/fail/ok/import-component.tc.ok +++ b/test/fail/ok/import-component.tc.ok @@ -1 +1 @@ -import-component.mo:3.8-3.28: RTS error [M0199], component import is unavailable (pass `-import-component` flag) +import-component.mo:3.8-3.28: RTS error [M0200], component import is unavailable (pass `-import-component` flag) From 330a295aee0ce817c1da765906892a9e3fa04ceb Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 12:44:19 -0600 Subject: [PATCH 07/30] Fix --- test/fail/import-component.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fail/import-component.mo b/test/fail/import-component.mo index 64ef04e7b0f..be06d273812 100644 --- a/test/fail/import-component.mo +++ b/test/fail/import-component.mo @@ -1,5 +1,5 @@ import P = "mo:⛔"; -ignore P.callComponent(123); +ignore P.componentCall(123); assert false; From 88744317512bacbc4fa0522dbbe2abd0587f9066 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 13:50:39 -0600 Subject: [PATCH 08/30] Rename test --- test/fail/{import-component.mo => M0200.mo} | 0 test/fail/ok/{import-component.tc.ok => M0200.tc.ok} | 0 test/fail/ok/{import-component.tc.ret.ok => M0200.tc.ret.ok} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/fail/{import-component.mo => M0200.mo} (100%) rename test/fail/ok/{import-component.tc.ok => M0200.tc.ok} (100%) rename test/fail/ok/{import-component.tc.ret.ok => M0200.tc.ret.ok} (100%) diff --git a/test/fail/import-component.mo b/test/fail/M0200.mo similarity index 100% rename from test/fail/import-component.mo rename to test/fail/M0200.mo diff --git a/test/fail/ok/import-component.tc.ok b/test/fail/ok/M0200.tc.ok similarity index 100% rename from test/fail/ok/import-component.tc.ok rename to test/fail/ok/M0200.tc.ok diff --git a/test/fail/ok/import-component.tc.ret.ok b/test/fail/ok/M0200.tc.ret.ok similarity index 100% rename from test/fail/ok/import-component.tc.ret.ok rename to test/fail/ok/M0200.tc.ret.ok From 74c5809fd0bff3953c74dde52c2c423722b3c0b8 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 13:54:04 -0600 Subject: [PATCH 09/30] Adjust error message --- src/codegen/compile.ml | 2 +- test/fail/ok/M0200.tc.ok | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 30b42b4cd91..3eb1d64df7e 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11255,7 +11255,7 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "componentCall", [e] -> if not !Flags.import_component then ( Printf.printf "%s" (Diag.string_of_message ( - Diag.error_message at "M0200" "RTS" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); + Diag.error_message at "M0200" "import" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); exit 1); SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ diff --git a/test/fail/ok/M0200.tc.ok b/test/fail/ok/M0200.tc.ok index c82dcd1af14..9d19d7d4ba0 100644 --- a/test/fail/ok/M0200.tc.ok +++ b/test/fail/ok/M0200.tc.ok @@ -1 +1 @@ -import-component.mo:3.8-3.28: RTS error [M0200], component import is unavailable (pass `-import-component` flag) +M0200.mo:3.8-3.28: import error [M0200], component import is unavailable (pass `-import-component` flag) From f4a63cb615b8d554966180847294b809be78ceca Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 15:19:47 -0600 Subject: [PATCH 10/30] Update test --- test/fail/M0200.mo | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/fail/M0200.mo b/test/fail/M0200.mo index be06d273812..18934ac9828 100644 --- a/test/fail/M0200.mo +++ b/test/fail/M0200.mo @@ -1,5 +1,3 @@ -import P = "mo:⛔"; +import Prim = "mo:⛔"; -ignore P.componentCall(123); - -assert false; +ignore Prim.componentCall(123); From 90f73616bce585ef0bc0520c9fcd4b7d8fc3609b Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 27 Jun 2024 16:26:01 -0600 Subject: [PATCH 11/30] Misc --- src/codegen/compile.ml | 2 +- test/fail/ok/M0200.tc.ok | 1 - test/fail/ok/M0200.tc.ret.ok | 1 - test/fail/ok/no-timer-canc.tc.ok | 1 + test/fail/ok/no-timer-set.tc.ok | 1 + 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 test/fail/ok/M0200.tc.ok delete mode 100644 test/fail/ok/M0200.tc.ret.ok diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 3eb1d64df7e..42a3b4b8561 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11256,7 +11256,7 @@ and compile_prim_invocation (env : E.t) ae p es at = if not !Flags.import_component then ( Printf.printf "%s" (Diag.string_of_message ( Diag.error_message at "M0200" "import" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); - exit 1); + exit 1); SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ E.call_import env "component" "call" diff --git a/test/fail/ok/M0200.tc.ok b/test/fail/ok/M0200.tc.ok deleted file mode 100644 index 9d19d7d4ba0..00000000000 --- a/test/fail/ok/M0200.tc.ok +++ /dev/null @@ -1 +0,0 @@ -M0200.mo:3.8-3.28: import error [M0200], component import is unavailable (pass `-import-component` flag) diff --git a/test/fail/ok/M0200.tc.ret.ok b/test/fail/ok/M0200.tc.ret.ok deleted file mode 100644 index 69becfa16f9..00000000000 --- a/test/fail/ok/M0200.tc.ret.ok +++ /dev/null @@ -1 +0,0 @@ -Return code 1 diff --git a/test/fail/ok/no-timer-canc.tc.ok b/test/fail/ok/no-timer-canc.tc.ok index 92026795a3e..186fc2c9afa 100644 --- a/test/fail/ok/no-timer-canc.tc.ok +++ b/test/fail/ok/no-timer-canc.tc.ok @@ -73,6 +73,7 @@ no-timer-canc.mo:3.10-3.21: type error [M0119], object field cancelTimer is not clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; + componentCall : Nat32 -> Nat32; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; diff --git a/test/fail/ok/no-timer-set.tc.ok b/test/fail/ok/no-timer-set.tc.ok index 42632af93d9..784bc492652 100644 --- a/test/fail/ok/no-timer-set.tc.ok +++ b/test/fail/ok/no-timer-set.tc.ok @@ -73,6 +73,7 @@ no-timer-set.mo:3.10-3.18: type error [M0119], object field setTimer is not cont clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; + componentCall : Nat32 -> Nat32; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; From d18df6d5ba71da0c9dde097e8c8950c93005f9de Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Fri, 28 Jun 2024 18:18:14 +0100 Subject: [PATCH 12/30] move M0200 error detection from compile.ml to typing.ml, using special @deprecation M0200 (#4584) --- src/codegen/compile.ml | 5 +---- src/mo_frontend/typing.ml | 5 ++++- src/prelude/prim.mo | 1 + test/fail/ok/M0200.tc.ok | 2 +- test/fail/ok/no-timer-canc.tc.ok | 1 + test/fail/ok/no-timer-set.tc.ok | 1 + 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 3eb1d64df7e..f1fb8e5fb83 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11253,10 +11253,7 @@ and compile_prim_invocation (env : E.t) ae p es at = E.call_import env "rts" "log" (* musl *) | OtherPrim "componentCall", [e] -> - if not !Flags.import_component then ( - Printf.printf "%s" (Diag.string_of_message ( - Diag.error_message at "M0200" "import" (Printf.sprintf "component import is unavailable (pass `-import-component` flag)"))); - exit 1); + assert !Flags.import_component; SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ E.call_import env "component" "call" diff --git a/src/mo_frontend/typing.ml b/src/mo_frontend/typing.ml index 136bdf4c708..0e8071a58a2 100644 --- a/src/mo_frontend/typing.ml +++ b/src/mo_frontend/typing.ml @@ -160,7 +160,10 @@ let check_deprecation env at desc id depr = | _ -> fun _ _ _ _ -> ()) env at code "this code is (or uses) the deprecated library `ExperimentalStableMemory`.\nPlease use the `Region` library instead: https://internetcomputer.org/docs/current/motoko/main/stable-memory/stable-regions/#the-region-library or compile with flag `--experimental-stable-memory 1` to suppress this message." - end + end + | Some ("M0200" as code) -> + if not !Flags.import_component then + error env at code "component import is unavailable (pass `-import-component` flag)" | Some msg -> warn env at "M0154" "%s %s is deprecated:\n%s" desc id msg | None -> () diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index cd9e11e853b..2ac9f98f4a9 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -269,6 +269,7 @@ func log(f : Float) : Float = (prim "flog" : Float -> Float) f; // Wasm component model functions +/// @deprecated M0200 func componentCall(n : Nat32) : Nat32 = (prim "componentCall" : Nat32 -> Nat32) n; // Array utilities diff --git a/test/fail/ok/M0200.tc.ok b/test/fail/ok/M0200.tc.ok index 9d19d7d4ba0..866b5baf5ad 100644 --- a/test/fail/ok/M0200.tc.ok +++ b/test/fail/ok/M0200.tc.ok @@ -1 +1 @@ -M0200.mo:3.8-3.28: import error [M0200], component import is unavailable (pass `-import-component` flag) +M0200.mo:3.8-3.23: type error [M0200], component import is unavailable (pass `-import-component` flag) diff --git a/test/fail/ok/no-timer-canc.tc.ok b/test/fail/ok/no-timer-canc.tc.ok index 92026795a3e..186fc2c9afa 100644 --- a/test/fail/ok/no-timer-canc.tc.ok +++ b/test/fail/ok/no-timer-canc.tc.ok @@ -73,6 +73,7 @@ no-timer-canc.mo:3.10-3.21: type error [M0119], object field cancelTimer is not clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; + componentCall : Nat32 -> Nat32; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; diff --git a/test/fail/ok/no-timer-set.tc.ok b/test/fail/ok/no-timer-set.tc.ok index 42632af93d9..784bc492652 100644 --- a/test/fail/ok/no-timer-set.tc.ok +++ b/test/fail/ok/no-timer-set.tc.ok @@ -73,6 +73,7 @@ no-timer-set.mo:3.10-3.18: type error [M0119], object field setTimer is not cont clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; + componentCall : Nat32 -> Nat32; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; From 3be8fd9013c32c608e44284c3aaedf07099c23f0 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 28 Jun 2024 11:23:51 -0600 Subject: [PATCH 13/30] Rename 'componentCall' prim to 'wit:component:call' --- src/codegen/compile.ml | 2 +- src/prelude/prim.mo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index f1fb8e5fb83..c719a534cd6 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11252,7 +11252,7 @@ and compile_prim_invocation (env : E.t) ae p es at = compile_exp_as env ae SR.UnboxedFloat64 e ^^ E.call_import env "rts" "log" (* musl *) - | OtherPrim "componentCall", [e] -> + | OtherPrim "wit:component:call", [e] -> assert !Flags.import_component; SR.UnboxedWord32 Type.Nat32, compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 2ac9f98f4a9..2cc763b01d0 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -270,7 +270,7 @@ func log(f : Float) : Float = (prim "flog" : Float -> Float) f; // Wasm component model functions /// @deprecated M0200 -func componentCall(n : Nat32) : Nat32 = (prim "componentCall" : Nat32 -> Nat32) n; +func componentCall(n : Nat32) : Nat32 = (prim "wit:component:call" : Nat32 -> Nat32) n; // Array utilities From 36bf9ad033f8917072f9321b1d25050da0b8be71 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 28 Jun 2024 12:01:01 -0600 Subject: [PATCH 14/30] Accept new test output --- test/fail/ok/M0200.tc.ok | 2 +- test/fail/ok/M0200.tc.ret.ok | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/fail/ok/M0200.tc.ret.ok diff --git a/test/fail/ok/M0200.tc.ok b/test/fail/ok/M0200.tc.ok index 866b5baf5ad..7f473a1d286 100644 --- a/test/fail/ok/M0200.tc.ok +++ b/test/fail/ok/M0200.tc.ok @@ -1 +1 @@ -M0200.mo:3.8-3.23: type error [M0200], component import is unavailable (pass `-import-component` flag) +M0200.mo:3.8-3.26: type error [M0200], component import is unavailable (pass `-import-component` flag) diff --git a/test/fail/ok/M0200.tc.ret.ok b/test/fail/ok/M0200.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/M0200.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 From 68bca73d4acd7eb5629d58ba5fa0d4d63e4cde01 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 28 Jun 2024 11:36:06 -0600 Subject: [PATCH 15/30] Set up `Blob -> Blob` function type --- src/codegen/compile.ml | 6 +++--- src/prelude/prim.mo | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index c719a534cd6..335e1178509 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11254,8 +11254,8 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "wit:component:call", [e] -> assert !Flags.import_component; - SR.UnboxedWord32 Type.Nat32, - compile_exp_as env ae (SR.UnboxedWord32 Type.Nat32) e ^^ + SR.Vanilla, + compile_exp_as env ae Sr.Vanilla e ^^ E.call_import env "component" "call" (* Other prims, nullary *) @@ -12826,7 +12826,7 @@ let compile mode rts (prog : Ir.prog) : Wasm_exts.CustomModule.extended_module = (* Wasm component model *) if !Flags.import_component then - E.add_func_import env "component" "call" [I32Type] [I32Type]; + E.add_func_import env "component" "call" [I32Type; I32Type] [I32Type]; compile_init_func env prog; let start_fi_o = match E.mode env with diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 2cc763b01d0..5a2a41a5148 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -270,7 +270,7 @@ func log(f : Float) : Float = (prim "flog" : Float -> Float) f; // Wasm component model functions /// @deprecated M0200 -func componentCall(n : Nat32) : Nat32 = (prim "wit:component:call" : Nat32 -> Nat32) n; +func componentCall(b : Blob) : Blob = (prim "wit:component:call" : Blob -> Blob) b; // Array utilities From 866e7786ad3d64bcb4ecf759b43e942739c0e820 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Mon, 1 Jul 2024 16:05:34 -0600 Subject: [PATCH 16/30] Temporarily use unboxed constant expressions --- src/codegen/compile.ml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 335e1178509..762e034ae73 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11254,8 +11254,10 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "wit:component:call", [e] -> assert !Flags.import_component; - SR.Vanilla, - compile_exp_as env ae Sr.Vanilla e ^^ + SR.UnboxedWord32 Type.Nat32, + (* compile_exp_as env ae SR.Vanilla e ^^ *) + compile_unboxed_const 0l ^^ + compile_unboxed_const 0l ^^ E.call_import env "component" "call" (* Other prims, nullary *) From 9100f65326184091216879f1b55759274c853e41 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 10 Jul 2024 11:06:49 -0600 Subject: [PATCH 17/30] Use Blob arg in place of Nat32 --- src/codegen/compile.ml | 8 +++++--- src/prelude/prim.mo | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 762e034ae73..a7e162d1ac3 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11255,9 +11255,11 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "wit:component:call", [e] -> assert !Flags.import_component; SR.UnboxedWord32 Type.Nat32, - (* compile_exp_as env ae SR.Vanilla e ^^ *) - compile_unboxed_const 0l ^^ - compile_unboxed_const 0l ^^ + compile_exp_as env ae SR.Vanilla e ^^ + let set_blob, get_blob = new_local env "blob" in + set_blob ^^ + get_blob ^^ Blob.payload_ptr_unskewed env ^^ + get_blob ^^ Blob.len env ^^ E.call_import env "component" "call" (* Other prims, nullary *) diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 5a2a41a5148..69a740eebe8 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -270,7 +270,7 @@ func log(f : Float) : Float = (prim "flog" : Float -> Float) f; // Wasm component model functions /// @deprecated M0200 -func componentCall(b : Blob) : Blob = (prim "wit:component:call" : Blob -> Blob) b; +func componentCall(b : Blob) : Nat32 = (prim "wit:component:call" : Blob -> Nat32) b; // Array utilities From fabbb7ce4f337b2e1ee3e8471cf0a2e5a7ec286c Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 10 Jul 2024 13:25:25 -0600 Subject: [PATCH 18/30] Progress --- rts/motoko-rts/src/component.rs | 23 +++++++++++++++++++++++ rts/motoko-rts/src/lib.rs | 1 + src/codegen/compile.ml | 5 +++-- 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 rts/motoko-rts/src/component.rs diff --git a/rts/motoko-rts/src/component.rs b/rts/motoko-rts/src/component.rs new file mode 100644 index 00000000000..51a48fa4a0d --- /dev/null +++ b/rts/motoko-rts/src/component.rs @@ -0,0 +1,23 @@ +// Wasm Component Model utilities + +use crate::{ + barriers::allocation_barrier, + memory::{alloc_blob, Memory}, + types::Value, + Bytes, +}; +use alloc::vec::Vec; +use motoko_rts_macros::ic_mem_fn; + +/// Convert a Canonical ABI `list` to a Motoko `Blob`. +#[ic_mem_fn] +unsafe fn blob_of_cabi_list_u8(mem: &mut M, vec: Vec) -> Value { + let value = alloc_blob(mem, Bytes(vec.len() as u32)); + let blob = value.as_blob_mut(); + let mut dest = blob.payload_addr(); + for item in vec.into_iter() { + *dest = item; + dest = dest.add(1); + } + allocation_barrier(value) +} diff --git a/rts/motoko-rts/src/lib.rs b/rts/motoko-rts/src/lib.rs index fd2f6f169e0..94f303cf6ae 100644 --- a/rts/motoko-rts/src/lib.rs +++ b/rts/motoko-rts/src/lib.rs @@ -26,6 +26,7 @@ pub mod bitrel; mod blob_iter; pub mod buf; mod char; +mod component; pub mod constants; pub mod continuation_table; #[cfg(feature = "ic")] diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index a7e162d1ac3..8c190d7f61d 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -1258,7 +1258,7 @@ module RTS = struct E.add_func_import env "rts" "stream_split" [I32Type] [I32Type]; E.add_func_import env "rts" "stream_shutdown" [I32Type] []; E.add_func_import env "rts" "stream_reserve" [I32Type; I32Type] [I32Type]; - E.add_func_import env "rts" "stream_stable_dest" [I32Type; I64Type; I64Type] []; + E.add_func_import env "rts" "blob_of_cabi_list_u8" [I32Type; I32Type] [I32Type]; if !Flags.gc_strategy = Flags.Incremental then incremental_gc_imports env else @@ -11260,7 +11260,8 @@ and compile_prim_invocation (env : E.t) ae p es at = set_blob ^^ get_blob ^^ Blob.payload_ptr_unskewed env ^^ get_blob ^^ Blob.len env ^^ - E.call_import env "component" "call" + E.call_import env "component" "call" ^^ + E.call_import env "rts" "blob_of_cabi_list_u8" (* Other prims, nullary *) From 64d0091221ed652abaf10a100d79950cb121f43d Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 10 Jul 2024 13:54:31 -0600 Subject: [PATCH 19/30] Accept new test output --- test/fail/ok/no-timer-canc.tc.ok | 2 +- test/fail/ok/no-timer-set.tc.ok | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fail/ok/no-timer-canc.tc.ok b/test/fail/ok/no-timer-canc.tc.ok index 186fc2c9afa..155084b6da8 100644 --- a/test/fail/ok/no-timer-canc.tc.ok +++ b/test/fail/ok/no-timer-canc.tc.ok @@ -73,7 +73,7 @@ no-timer-canc.mo:3.10-3.21: type error [M0119], object field cancelTimer is not clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; - componentCall : Nat32 -> Nat32; + componentCall : Blob -> Nat32; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; diff --git a/test/fail/ok/no-timer-set.tc.ok b/test/fail/ok/no-timer-set.tc.ok index 784bc492652..96201e3c855 100644 --- a/test/fail/ok/no-timer-set.tc.ok +++ b/test/fail/ok/no-timer-set.tc.ok @@ -73,7 +73,7 @@ no-timer-set.mo:3.10-3.18: type error [M0119], object field setTimer is not cont clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; - componentCall : Nat32 -> Nat32; + componentCall : Blob -> Nat32; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; From 5d9d4965857da9d9d91ef00213cfbc2f7867118c Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 10 Jul 2024 17:40:27 -0600 Subject: [PATCH 20/30] Implement Blob return value --- rts/motoko-rts/src/component.rs | 18 ++++++++++-------- src/codegen/compile.ml | 17 ++++++++++++----- src/prelude/prim.mo | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/rts/motoko-rts/src/component.rs b/rts/motoko-rts/src/component.rs index 51a48fa4a0d..b8475cf5e93 100644 --- a/rts/motoko-rts/src/component.rs +++ b/rts/motoko-rts/src/component.rs @@ -6,18 +6,20 @@ use crate::{ types::Value, Bytes, }; -use alloc::vec::Vec; use motoko_rts_macros::ic_mem_fn; -/// Convert a Canonical ABI `list` to a Motoko `Blob`. +/// Convert a Canonical ABI `list` pointer to a Motoko `Blob`. #[ic_mem_fn] -unsafe fn blob_of_cabi_list_u8(mem: &mut M, vec: Vec) -> Value { - let value = alloc_blob(mem, Bytes(vec.len() as u32)); +unsafe fn blob_of_cabi(mem: &mut M, ret: *const u32) -> Value { + let items = *ret as *const u8; // Note: 32-bit address + let len = *ret.add(1); + + // TODO: use existing Blob from `cabi_realloc`? + let value = alloc_blob(mem, Bytes(len)); let blob = value.as_blob_mut(); - let mut dest = blob.payload_addr(); - for item in vec.into_iter() { - *dest = item; - dest = dest.add(1); + let dest = blob.payload_addr(); + for i in 0..len as usize { + *dest.add(i) = *items.add(i); } allocation_barrier(value) } diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 8c190d7f61d..1da721c8058 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -1258,7 +1258,7 @@ module RTS = struct E.add_func_import env "rts" "stream_split" [I32Type] [I32Type]; E.add_func_import env "rts" "stream_shutdown" [I32Type] []; E.add_func_import env "rts" "stream_reserve" [I32Type; I32Type] [I32Type]; - E.add_func_import env "rts" "blob_of_cabi_list_u8" [I32Type; I32Type] [I32Type]; + E.add_func_import env "rts" "blob_of_cabi" [I32Type] [I32Type]; if !Flags.gc_strategy = Flags.Incremental then incremental_gc_imports env else @@ -11255,13 +11255,20 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "wit:component:call", [e] -> assert !Flags.import_component; SR.UnboxedWord32 Type.Nat32, - compile_exp_as env ae SR.Vanilla e ^^ + (* Read blob pointer and length *) let set_blob, get_blob = new_local env "blob" in - set_blob ^^ + compile_exp_as env ae SR.Vanilla e ^^ set_blob ^^ + (* Allocate return value *) + let set_ret, get_ret = new_local env "ret" in + (* TODO: optimize *) + Blob.lit env "\x00\x00" ^^ set_ret ^^ + (* Call component export *) get_blob ^^ Blob.payload_ptr_unskewed env ^^ get_blob ^^ Blob.len env ^^ + get_ret ^^ Blob.payload_ptr_unskewed env ^^ E.call_import env "component" "call" ^^ - E.call_import env "rts" "blob_of_cabi_list_u8" + get_ret ^^ + E.call_import env "rts" "blob_of_cabi" (* Other prims, nullary *) @@ -12831,7 +12838,7 @@ let compile mode rts (prog : Ir.prog) : Wasm_exts.CustomModule.extended_module = (* Wasm component model *) if !Flags.import_component then - E.add_func_import env "component" "call" [I32Type; I32Type] [I32Type]; + E.add_func_import env "component" "call" [I32Type; I32Type; I32Type] []; compile_init_func env prog; let start_fi_o = match E.mode env with diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 69a740eebe8..5a2a41a5148 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -270,7 +270,7 @@ func log(f : Float) : Float = (prim "flog" : Float -> Float) f; // Wasm component model functions /// @deprecated M0200 -func componentCall(b : Blob) : Nat32 = (prim "wit:component:call" : Blob -> Nat32) b; +func componentCall(b : Blob) : Blob = (prim "wit:component:call" : Blob -> Blob) b; // Array utilities From 1397ed853dc737789cd5beb5253888cad93caa3f Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 10 Jul 2024 17:41:08 -0600 Subject: [PATCH 21/30] Rename local variable --- 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 5a2a41a5148..90b6983fc5a 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -270,7 +270,7 @@ func log(f : Float) : Float = (prim "flog" : Float -> Float) f; // Wasm component model functions /// @deprecated M0200 -func componentCall(b : Blob) : Blob = (prim "wit:component:call" : Blob -> Blob) b; +func componentCall(value : Blob) : Blob = (prim "wit:component:call" : Blob -> Blob) value; // Array utilities From 1a6b821c033860bec305ebe45d8708a609b192ca Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 10 Jul 2024 18:18:11 -0600 Subject: [PATCH 22/30] Set up 'cabi_realloc' --- rts/motoko-rts/src/component.rs | 30 ++++++++++++++++++++++++++++++ src/codegen/compile.ml | 14 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/rts/motoko-rts/src/component.rs b/rts/motoko-rts/src/component.rs index b8475cf5e93..6a3a00d04b4 100644 --- a/rts/motoko-rts/src/component.rs +++ b/rts/motoko-rts/src/component.rs @@ -23,3 +23,33 @@ unsafe fn blob_of_cabi(mem: &mut M, ret: *const u32) -> Value { } allocation_barrier(value) } + +/// Canonical ABI allocation logic. +/// Derived from: https://docs.rs/wit-bindgen-rt/0.27.0/src/wit_bindgen_rt/lib.rs.html#54-88 +#[ic_mem_fn] +unsafe fn cabi_realloc( + _mem: &mut M, + old_ptr: *mut u8, + old_len: usize, + align: usize, + new_len: usize, +) -> *mut u8 { + use ::alloc::alloc::{self, Layout}; + + let layout; + let ptr = if old_len == 0 { + if new_len == 0 { + return align as *mut u8; + } + layout = Layout::from_size_align_unchecked(new_len, align); + alloc::alloc(layout) + } else { + debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!"); + layout = Layout::from_size_align_unchecked(old_len, align); + alloc::realloc(old_ptr, layout, new_len) + }; + if ptr.is_null() { + unreachable!(); + } + return ptr; +} diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 1da721c8058..3ef5982dd17 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -1259,6 +1259,7 @@ module RTS = struct E.add_func_import env "rts" "stream_shutdown" [I32Type] []; E.add_func_import env "rts" "stream_reserve" [I32Type; I32Type] [I32Type]; E.add_func_import env "rts" "blob_of_cabi" [I32Type] [I32Type]; + E.add_func_import env "rts" "cabi_realloc" [I32Type; I32Type; I32Type; I32Type] [I32Type]; if !Flags.gc_strategy = Flags.Incremental then incremental_gc_imports env else @@ -6337,6 +6338,19 @@ module RTS_Exports = struct E.add_export env (nr { name = Lib.Utf8.decode "moc_stable_mem_set_version"; edesc = nr (FuncExport (nr moc_stable_mem_set_version_fi)) + }); + + let cabi_realloc = + E.add_fun env "cabi_realloc" ( + Func.of_body env ["ptr", I32Type; "len", I32Type; "align", I32Type; "new_len", I32Type] [I32Type] + (fun env -> + E.call_import env "rts" "cabi_realloc" + ) + ) + in + E.add_export env (nr { + name = Lib.Utf8.decode "cabi_realloc"; + edesc = nr (FuncExport (nr cabi_realloc)) }) end (* RTS_Exports *) From c75164056a055865434d894f6a942c290634e84e Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 11 Jul 2024 11:10:25 -0600 Subject: [PATCH 23/30] Export 'cabi_realloc' --- src/codegen/compile.ml | 21 ++++----------------- src/lang_utils/error_codes/M0200.md | 2 +- src/linking/linkModule.ml | 1 + src/prelude/prim.mo | 2 +- 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 3ef5982dd17..dc7034eab32 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -1258,8 +1258,9 @@ module RTS = struct E.add_func_import env "rts" "stream_split" [I32Type] [I32Type]; E.add_func_import env "rts" "stream_shutdown" [I32Type] []; E.add_func_import env "rts" "stream_reserve" [I32Type; I32Type] [I32Type]; - E.add_func_import env "rts" "blob_of_cabi" [I32Type] [I32Type]; - E.add_func_import env "rts" "cabi_realloc" [I32Type; I32Type; I32Type; I32Type] [I32Type]; + if !Flags.import_component then ( + E.add_func_import env "rts" "blob_of_cabi" [I32Type] [I32Type]; + E.add_func_import env "rts" "cabi_realloc" [I32Type; I32Type; I32Type; I32Type] [I32Type]); if !Flags.gc_strategy = Flags.Incremental then incremental_gc_imports env else @@ -5260,7 +5261,6 @@ module IC = struct edesc = nr (FuncExport (nr post_upgrade_fi)) }) - let get_self_reference env = match E.mode env with | Flags.ICMode | Flags.RefMode -> @@ -6340,19 +6340,6 @@ module RTS_Exports = struct edesc = nr (FuncExport (nr moc_stable_mem_set_version_fi)) }); - let cabi_realloc = - E.add_fun env "cabi_realloc" ( - Func.of_body env ["ptr", I32Type; "len", I32Type; "align", I32Type; "new_len", I32Type] [I32Type] - (fun env -> - E.call_import env "rts" "cabi_realloc" - ) - ) - in - E.add_export env (nr { - name = Lib.Utf8.decode "cabi_realloc"; - edesc = nr (FuncExport (nr cabi_realloc)) - }) - end (* RTS_Exports *) @@ -12850,7 +12837,7 @@ let compile mode rts (prog : Ir.prog) : Wasm_exts.CustomModule.extended_module = IC.system_imports env; RTS.system_imports env; - (* Wasm component model *) + (* Wasm Component Model *) if !Flags.import_component then E.add_func_import env "component" "call" [I32Type; I32Type; I32Type] []; diff --git a/src/lang_utils/error_codes/M0200.md b/src/lang_utils/error_codes/M0200.md index 09e040ac8f3..5f200ab4425 100644 --- a/src/lang_utils/error_codes/M0200.md +++ b/src/lang_utils/error_codes/M0200.md @@ -1,5 +1,5 @@ # M0200 -This error indicates that the Wasm component model (cross-language) functionality is not enabled. +This error indicates that the Wasm Component Model (cross-language) functionality is not enabled. You can fix this by passing the `-import-component` compiler flag, e.g. `moc -wasi-system-api -import-component ...`. diff --git a/src/linking/linkModule.ml b/src/linking/linkModule.ml index f48f9e67eca..c24e52c02d1 100644 --- a/src/linking/linkModule.ml +++ b/src/linking/linkModule.ml @@ -258,6 +258,7 @@ let remove_non_ic_exports (em : extended_module) : extended_module = exported in the final module *) let is_ic_export (exp : export) = Lib.String.chop_prefix "canister_" (Lib.Utf8.encode exp.it.name) <> None || + (!Mo_config.Flags.import_component && Lib.String.chop_prefix "cabi_" (Lib.Utf8.encode exp.it.name) <> None) || (* Wasm Component Model *) "_start" = Lib.Utf8.encode exp.it.name in diff --git a/src/prelude/prim.mo b/src/prelude/prim.mo index 90b6983fc5a..93376bdcc7c 100644 --- a/src/prelude/prim.mo +++ b/src/prelude/prim.mo @@ -267,7 +267,7 @@ func arctan2(y : Float, x : Float) : Float = (prim "fatan2" : (Float, Float) -> func exp(f : Float) : Float = (prim "fexp" : Float -> Float) f; func log(f : Float) : Float = (prim "flog" : Float -> Float) f; -// Wasm component model functions +// Wasm Component Model functions /// @deprecated M0200 func componentCall(value : Blob) : Blob = (prim "wit:component:call" : Blob -> Blob) value; From 97a5ebb3dc415a9395d174c50dc3c7b0eff53777 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 11 Jul 2024 11:29:36 -0600 Subject: [PATCH 24/30] Simplify --- rts/motoko-rts/src/component.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rts/motoko-rts/src/component.rs b/rts/motoko-rts/src/component.rs index 6a3a00d04b4..3892330ea3a 100644 --- a/rts/motoko-rts/src/component.rs +++ b/rts/motoko-rts/src/component.rs @@ -14,7 +14,7 @@ unsafe fn blob_of_cabi(mem: &mut M, ret: *const u32) -> Value { let items = *ret as *const u8; // Note: 32-bit address let len = *ret.add(1); - // TODO: use existing Blob from `cabi_realloc`? + // TODO: reuse memory space from `cabi_realloc`? let value = alloc_blob(mem, Bytes(len)); let blob = value.as_blob_mut(); let dest = blob.payload_addr(); @@ -51,5 +51,5 @@ unsafe fn cabi_realloc( if ptr.is_null() { unreachable!(); } - return ptr; + ptr } From 93f50893675d0000f3d6a50bb8dacd98263b7d28 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Thu, 11 Jul 2024 12:47:07 -0600 Subject: [PATCH 25/30] Working 'Blob -> Blob' component call logic --- rts/motoko-rts/src/component.rs | 12 +++++++----- src/codegen/compile.ml | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/rts/motoko-rts/src/component.rs b/rts/motoko-rts/src/component.rs index 3892330ea3a..5553ac0c5a4 100644 --- a/rts/motoko-rts/src/component.rs +++ b/rts/motoko-rts/src/component.rs @@ -6,16 +6,18 @@ use crate::{ types::Value, Bytes, }; +use alloc as alloc_crate; +use core::convert::TryInto; use motoko_rts_macros::ic_mem_fn; /// Convert a Canonical ABI `list` pointer to a Motoko `Blob`. #[ic_mem_fn] -unsafe fn blob_of_cabi(mem: &mut M, ret: *const u32) -> Value { - let items = *ret as *const u8; // Note: 32-bit address +unsafe fn blob_of_cabi(mem: &mut M, ret: *const usize) -> Value { + let items = *ret as *const u8; let len = *ret.add(1); - // TODO: reuse memory space from `cabi_realloc`? - let value = alloc_blob(mem, Bytes(len)); + // TODO: reuse Blob from `cabi_realloc`? + let value = alloc_blob(mem, Bytes(len.try_into().unwrap())); // Checked conversion from `usize` to `u32` let blob = value.as_blob_mut(); let dest = blob.payload_addr(); for i in 0..len as usize { @@ -34,7 +36,7 @@ unsafe fn cabi_realloc( align: usize, new_len: usize, ) -> *mut u8 { - use ::alloc::alloc::{self, Layout}; + use alloc_crate::alloc::{self, Layout}; let layout; let ptr = if old_len == 0 { diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index dc7034eab32..3747a13735e 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11255,20 +11255,20 @@ and compile_prim_invocation (env : E.t) ae p es at = | OtherPrim "wit:component:call", [e] -> assert !Flags.import_component; - SR.UnboxedWord32 Type.Nat32, + SR.Vanilla, (* Read blob pointer and length *) let set_blob, get_blob = new_local env "blob" in compile_exp_as env ae SR.Vanilla e ^^ set_blob ^^ (* Allocate return value *) let set_ret, get_ret = new_local env "ret" in - (* TODO: optimize *) + (* TODO: optimize? *) Blob.lit env "\x00\x00" ^^ set_ret ^^ (* Call component export *) get_blob ^^ Blob.payload_ptr_unskewed env ^^ get_blob ^^ Blob.len env ^^ get_ret ^^ Blob.payload_ptr_unskewed env ^^ E.call_import env "component" "call" ^^ - get_ret ^^ + get_ret ^^ Blob.payload_ptr_unskewed env ^^ E.call_import env "rts" "blob_of_cabi" (* Other prims, nullary *) From b6df7a1e600ec3ac26760f1e391c15cacf39668b Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 12 Jul 2024 09:22:51 -0600 Subject: [PATCH 26/30] Misc --- rts/motoko-rts/src/component.rs | 4 ++-- src/codegen/compile.ml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rts/motoko-rts/src/component.rs b/rts/motoko-rts/src/component.rs index 5553ac0c5a4..f74805d5a2c 100644 --- a/rts/motoko-rts/src/component.rs +++ b/rts/motoko-rts/src/component.rs @@ -13,7 +13,7 @@ use motoko_rts_macros::ic_mem_fn; /// Convert a Canonical ABI `list` pointer to a Motoko `Blob`. #[ic_mem_fn] unsafe fn blob_of_cabi(mem: &mut M, ret: *const usize) -> Value { - let items = *ret as *const u8; + let content = *ret as *const u8; let len = *ret.add(1); // TODO: reuse Blob from `cabi_realloc`? @@ -21,7 +21,7 @@ unsafe fn blob_of_cabi(mem: &mut M, ret: *const usize) -> Value { let blob = value.as_blob_mut(); let dest = blob.payload_addr(); for i in 0..len as usize { - *dest.add(i) = *items.add(i); + *dest.add(i) = *content.add(i); } allocation_barrier(value) } diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 3747a13735e..d2c4b1e4aba 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -11262,7 +11262,7 @@ and compile_prim_invocation (env : E.t) ae p es at = (* Allocate return value *) let set_ret, get_ret = new_local env "ret" in (* TODO: optimize? *) - Blob.lit env "\x00\x00" ^^ set_ret ^^ + Blob.lit env "\x00\x00\x00\x00\x00\x00\x00\x00" ^^ set_ret ^^ (* pointer, length *) (* Call component export *) get_blob ^^ Blob.payload_ptr_unskewed env ^^ get_blob ^^ Blob.len env ^^ From cd5fa0204c472f65d0c3fda59d6637de301d94bd Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 19 Jul 2024 16:03:25 -0600 Subject: [PATCH 27/30] Fix missing RTS import --- src/codegen/compile.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index d2c4b1e4aba..e72553316a5 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -1258,6 +1258,7 @@ module RTS = struct E.add_func_import env "rts" "stream_split" [I32Type] [I32Type]; E.add_func_import env "rts" "stream_shutdown" [I32Type] []; E.add_func_import env "rts" "stream_reserve" [I32Type; I32Type] [I32Type]; + E.add_func_import env "rts" "stream_stable_dest" [I32Type; I64Type; I64Type] []; if !Flags.import_component then ( E.add_func_import env "rts" "blob_of_cabi" [I32Type] [I32Type]; E.add_func_import env "rts" "cabi_realloc" [I32Type; I32Type; I32Type; I32Type] [I32Type]); From 4b95c4f31faf757c7786aba23c479caae2112352 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 19 Jul 2024 16:05:28 -0600 Subject: [PATCH 28/30] Reduce diff --- src/codegen/compile.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 1458b70cadd..82b52c64607 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -5266,6 +5266,7 @@ module IC = struct edesc = nr (FuncExport (nr post_upgrade_fi)) }) + let get_self_reference env = match E.mode env with | Flags.ICMode | Flags.RefMode -> @@ -6343,7 +6344,7 @@ module RTS_Exports = struct E.add_export env (nr { name = Lib.Utf8.decode "moc_stable_mem_set_version"; edesc = nr (FuncExport (nr moc_stable_mem_set_version_fi)) - }); + }) end (* RTS_Exports *) From bf1fe7d9a6614578daac1e9cea3fd9a63c5f590d Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 19 Jul 2024 16:59:22 -0600 Subject: [PATCH 29/30] Update heap-32 test --- test/bench/ok/heap-32.drun-run-opt.ok | 2 +- test/bench/ok/heap-32.drun-run.ok | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bench/ok/heap-32.drun-run-opt.ok b/test/bench/ok/heap-32.drun-run-opt.ok index faf3bfb29da..f5ae73261f4 100644 --- a/test/bench/ok/heap-32.drun-run-opt.ok +++ b/test/bench/ok/heap-32.drun-run-opt.ok @@ -1,5 +1,5 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 debug.print: (50_227, +29_863_068, 708_174_952) -debug.print: (50_070, +32_992_212, 766_613_680) +debug.print: (50_070, +32_992_212, 766_613_760) ingress Completed: Reply: 0x4449444c0000 diff --git a/test/bench/ok/heap-32.drun-run.ok b/test/bench/ok/heap-32.drun-run.ok index f51bd0ff0c3..b67b6f2e41b 100644 --- a/test/bench/ok/heap-32.drun-run.ok +++ b/test/bench/ok/heap-32.drun-run.ok @@ -1,5 +1,5 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 ingress Completed: Reply: 0x4449444c0000 debug.print: (50_227, +29_863_068, 769_000_085) -debug.print: (50_070, +32_992_212, 830_427_376) +debug.print: (50_070, +32_992_212, 830_427_500) ingress Completed: Reply: 0x4449444c0000 From 39125814f236f462c950594670a7e01a3f15dc35 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Fri, 19 Jul 2024 17:21:07 -0600 Subject: [PATCH 30/30] Adjust more tests --- test/fail/ok/no-timer-canc.tc.ok | 2 +- test/fail/ok/no-timer-set.tc.ok | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fail/ok/no-timer-canc.tc.ok b/test/fail/ok/no-timer-canc.tc.ok index d7ae69fa6f1..c404544e2c6 100644 --- a/test/fail/ok/no-timer-canc.tc.ok +++ b/test/fail/ok/no-timer-canc.tc.ok @@ -74,7 +74,7 @@ no-timer-canc.mo:3.10-3.21: type error [M0119], object field cancelTimer is not clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; - componentCall : Blob -> Nat32; + componentCall : Blob -> Blob; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16; diff --git a/test/fail/ok/no-timer-set.tc.ok b/test/fail/ok/no-timer-set.tc.ok index 41a1e2922ac..89c1a56824b 100644 --- a/test/fail/ok/no-timer-set.tc.ok +++ b/test/fail/ok/no-timer-set.tc.ok @@ -74,7 +74,7 @@ no-timer-set.mo:3.10-3.18: type error [M0119], object field setTimer is not cont clzNat32 : Nat32 -> Nat32; clzNat64 : Nat64 -> Nat64; clzNat8 : Nat8 -> Nat8; - componentCall : Blob -> Nat32; + componentCall : Blob -> Blob; cos : Float -> Float; createActor : (Blob, Blob) -> async Principal; ctzInt16 : Int16 -> Int16;