Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add prim deadline for receiver-side best-effort messages #4795

Merged
merged 19 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Motoko compiler changelog

## 0.13.5 (FUTURE)

* motoko (`moc`)

* Added new primitive `replyDeadline : () -> Nat64` to obtain when a response for a best-effort message is due (#4795).

* motoko-base

* Added `Text.fromList` and `Text.toList` functions (dfinity/motoko-base#676).

* Added `Text.fromArray/fromVarArray` functions (dfinity/motoko-base#674).

## 0.13.4 (2024-11-29)

* motoko (`moc`)
Expand Down
6 changes: 3 additions & 3 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
"homepage": "",
"owner": "luc-blaeser",
"repo": "ic",
"rev": "33075cd385ea2ec4170f522406b1ff8f507fa744",
"sha256": "0swx7r78wjybx7fkfqsn9p3lqxmszgg24q4hrnxmscvyhb22hqia",
"rev": "bebe89514a6abd26e940b295323823169911a965",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enables the ic0.msg_deadline in drun

"sha256": "1g68fyi5acbcgs2kjribk97fj8ki5g6pd99nwl5azz1rw1b0xycx",
"type": "tarball",
"url": "https://github.com/luc-blaeser/ic/archive/33075cd385ea2ec4170f522406b1ff8f507fa744.tar.gz",
"url": "https://github.com/luc-blaeser/ic/archive/bebe89514a6abd26e940b295323823169911a965.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ic-hs": {
Expand Down
21 changes: 16 additions & 5 deletions src/codegen/compile_classical.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5086,6 +5086,7 @@ module IC = struct
E.add_func_import env "ic0" "msg_reject" (i32s 2) [];
E.add_func_import env "ic0" "msg_reply_data_append" (i32s 2) [];
E.add_func_import env "ic0" "msg_reply" [] [];
E.add_func_import env "ic0" "msg_deadline" [] [I64Type];
E.add_func_import env "ic0" "performance_counter" [I32Type] [I64Type];
E.add_func_import env "ic0" "trap" (i32s 2) [];
E.add_func_import env "ic0" "stable64_write" (i64s 3) [];
Expand Down Expand Up @@ -5351,7 +5352,7 @@ module IC = struct
(fun env -> system_call env "msg_caller_copy")
(fun env -> compile_unboxed_const 0l)
| _ ->
E.trap_with env (Printf.sprintf "cannot get caller when running locally")
E.trap_with env "cannot get caller when running locally"

let method_name env =
match E.mode env with
Expand All @@ -5361,7 +5362,7 @@ module IC = struct
(fun env -> system_call env "msg_method_name_copy")
(fun env -> compile_unboxed_const 0l)
| _ ->
E.trap_with env (Printf.sprintf "cannot get method_name when running locally")
E.trap_with env "cannot get method_name when running locally"

let arg_data env =
match E.mode env with
Expand All @@ -5371,7 +5372,14 @@ module IC = struct
(fun env -> system_call env "msg_arg_data_copy")
(fun env -> compile_unboxed_const 0l)
| _ ->
E.trap_with env (Printf.sprintf "cannot get arg_data when running locally")
E.trap_with env "cannot get arg_data when running locally"

let deadline env =
match E.mode env with
| Flags.(ICMode | RefMode) ->
system_call env "msg_deadline"
| _ ->
E.trap_with env "cannot get deadline when running locally"

let reject env arg_instrs =
match E.mode env with
Expand All @@ -5381,7 +5389,7 @@ module IC = struct
Blob.as_ptr_len env ^^
system_call env "msg_reject"
| _ ->
E.trap_with env (Printf.sprintf "cannot reject when running locally")
E.trap_with env "cannot reject when running locally"

let error_code env =
Func.share_code0 Func.Always env "error_code" [I32Type] (fun env ->
Expand Down Expand Up @@ -12095,7 +12103,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
Serialization.serialize env ts ^^
IC.reply_with_data env
| _ ->
E.trap_with env (Printf.sprintf "cannot reply when running locally")
E.trap_with env "cannot reply when running locally"
end

| ICRejectPrim, [e] ->
Expand Down Expand Up @@ -12144,6 +12152,9 @@ and compile_prim_invocation (env : E.t) ae p es at =
| ICMethodNamePrim, [] ->
SR.Vanilla, IC.method_name env

| ICReplyDeadlinePrim, [] ->
SR.UnboxedWord64 Type.Nat64, IC.deadline env

| ICStableRead ty, [] ->
(*
* On initial install:
Expand Down
21 changes: 16 additions & 5 deletions src/codegen/compile_enhanced.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4744,6 +4744,7 @@ module IC = struct
E.add_func_import env "ic0" "msg_reject" (i64s 2) [];
E.add_func_import env "ic0" "msg_reply_data_append" (i64s 2) [];
E.add_func_import env "ic0" "msg_reply" [] [];
E.add_func_import env "ic0" "msg_deadline" [] [I64Type];
E.add_func_import env "ic0" "performance_counter" [I32Type] [I64Type];
E.add_func_import env "ic0" "trap" (i64s 2) [];
E.add_func_import env "ic0" "stable64_write" (i64s 3) [];
Expand Down Expand Up @@ -5071,7 +5072,7 @@ module IC = struct
system_call env "msg_caller_copy")
(fun env -> compile_unboxed_const 0L)
| _ ->
E.trap_with env (Printf.sprintf "cannot get caller when running locally")
E.trap_with env "cannot get caller when running locally"

let method_name env =
match E.mode env with
Expand All @@ -5083,7 +5084,7 @@ module IC = struct
system_call env "msg_method_name_copy")
(fun env -> compile_unboxed_const 0L)
| _ ->
E.trap_with env (Printf.sprintf "cannot get method_name when running locally")
E.trap_with env "cannot get method_name when running locally"

let arg_data env =
match E.mode env with
Expand All @@ -5095,7 +5096,14 @@ module IC = struct
system_call env "msg_arg_data_copy")
(fun env -> compile_unboxed_const 0L)
| _ ->
E.trap_with env (Printf.sprintf "cannot get arg_data when running locally")
E.trap_with env "cannot get arg_data when running locally"

let deadline env =
match E.mode env with
| Flags.(ICMode | RefMode) ->
system_call env "msg_deadline"
| _ ->
E.trap_with env "cannot get deadline when running locally"

let reject env arg_instrs =
match E.mode env with
Expand All @@ -5105,7 +5113,7 @@ module IC = struct
Blob.as_ptr_len env ^^
system_call env "msg_reject"
| _ ->
E.trap_with env (Printf.sprintf "cannot reject when running locally")
E.trap_with env "cannot reject when running locally"

let error_code env =
Func.share_code0 Func.Always env "error_code" [I64Type] (fun env ->
Expand Down Expand Up @@ -12190,7 +12198,7 @@ and compile_prim_invocation (env : E.t) ae p es at =
Serialization.serialize env ts ^^
IC.reply_with_data env
| _ ->
E.trap_with env (Printf.sprintf "cannot reply when running locally")
E.trap_with env "cannot reply when running locally"
end

| ICRejectPrim, [e] ->
Expand Down Expand Up @@ -12239,6 +12247,9 @@ and compile_prim_invocation (env : E.t) ae p es at =
| ICMethodNamePrim, [] ->
SR.Vanilla, IC.method_name env

| ICReplyDeadlinePrim, [] ->
SR.UnboxedWord64 Type.Nat64, IC.deadline env

| ICStableRead ty, [] ->
SR.Vanilla,
Persistence.load env ty
Expand Down
1 change: 1 addition & 0 deletions src/ir_def/arrange_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ and prim = function
| ICCallPrim -> Atom "ICCallPrim"
| ICCallRawPrim -> Atom "ICCallRawPrim"
| ICMethodNamePrim -> Atom "ICMethodNamePrim"
| ICReplyDeadlinePrim -> Atom "ICReplyDeadlinePrim"
| ICStableWrite t -> "ICStableWrite" $$ [typ t]
| ICStableRead t -> "ICStableRead" $$ [typ t]

Expand Down
2 changes: 2 additions & 0 deletions src/ir_def/check_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ let rec check_exp env (exp:Ir.exp) : unit =
T.unit <: t
| ICMethodNamePrim, [] ->
T.text <: t
| ICReplyDeadlinePrim, [] ->
T.nat64 <: t
| ICStableRead t1, [] ->
check_typ env t1;
check (store_typ t1) "Invalid type argument to ICStableRead";
Expand Down
4 changes: 3 additions & 1 deletion src/ir_def/ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ and prim =
| ICCallPrim
| ICCallRawPrim
| ICMethodNamePrim
| ICReplyDeadlinePrim
| ICArgDataPrim
| ICStableWrite of Type.typ (* serialize value of stable type to stable memory *)
| ICStableRead of Type.typ (* deserialize value of stable type from stable memory *)
Expand Down Expand Up @@ -322,7 +323,8 @@ let map_prim t_typ t_id p =
| ICCallerPrim
| ICCallPrim
| ICCallRawPrim
| ICMethodNamePrim -> p
| ICMethodNamePrim
| ICReplyDeadlinePrim -> p
| ICStableWrite t -> ICStableWrite (t_typ t)
| ICStableRead t -> ICStableRead (t_typ t)
| ICStableSize t -> ICStableSize (t_typ t)
2 changes: 2 additions & 0 deletions src/ir_interpreter/interpret_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,8 @@ and interpret_exp_mut env exp (k : V.value V.cont) =
f (V.Tup[vc; kv; rv; cv]) v2 k
| ICCallerPrim, [] ->
k env.caller
| ICReplyDeadlinePrim, [] ->
k (V.Nat64 Numerics.Nat64.zero)
| ICStableRead t, [] ->
let (_, tfs) = T.as_obj t in
let ve = List.fold_left
Expand Down
3 changes: 3 additions & 0 deletions src/lowering/desugar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ and exp' at note = function
| S.CallE ({it=S.AnnotE ({it=S.PrimE "caller";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.ICCallerPrim, [])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "deadline";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.ICReplyDeadlinePrim, [])
| S.CallE ({it=S.AnnotE ({it=S.PrimE "time";_},_);_}, _, {it=S.TupE es;_}) ->
assert (es = []);
I.PrimE (I.SystemTimePrim, [])
Expand Down
1 change: 1 addition & 0 deletions src/mo_values/prim.ml
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ let prim trap =
| "rts_upgrade_instructions") ->
fun _ v k -> as_unit v; k (Int (Int.of_int 0))
| "time" -> fun _ v k -> as_unit v; k (Value.Nat64 (Numerics.Nat64.of_int 42))
| "deadline" -> fun _ v k -> as_unit v; k (Value.Nat64 Numerics.Nat64.zero)
| "idlHash" -> fun _ v k ->
let s = as_text v in
k (Nat32 (Nat32.wrapping_of_big_int (Big_int.big_int_of_int32 (Lib.Uint32.to_int32 (Idllib.IdlHash.idl_hash s)))))
Expand Down
4 changes: 4 additions & 0 deletions src/prelude/prim.mo
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ func error(message : Text) : Error {
func errorCode(e : Error) : ErrorCode = ((prim "cast" : Error -> (ErrorCode, Text)) e).0;
func errorMessage(e : Error) : Text = ((prim "cast" : Error -> (ErrorCode, Text)) e).1;

// Message deadline (best-effort messaging)

func replyDeadline() : Nat64 = (prim "deadline" : () -> Nat64) ();

// Time

func time() : Nat64 = (prim "time" : () -> Nat64)();
Expand Down
1 change: 1 addition & 0 deletions test/fail/ok/no-timer-canc.tc.ok
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ no-timer-canc.mo:3.10-3.21: type error [M0119], object field cancelTimer is not
regionStoreNat32 : (Region, Nat64, Nat32) -> ();
regionStoreNat64 : (Region, Nat64, Nat64) -> ();
regionStoreNat8 : (Region, Nat64, Nat8) -> ();
replyDeadline : () -> Nat64;
rts_callback_table_count : () -> Nat;
rts_callback_table_size : () -> Nat;
rts_collector_instructions : () -> Nat;
Expand Down
1 change: 1 addition & 0 deletions test/fail/ok/no-timer-set.tc.ok
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ no-timer-set.mo:3.10-3.18: type error [M0119], object field setTimer is not cont
regionStoreNat32 : (Region, Nat64, Nat32) -> ();
regionStoreNat64 : (Region, Nat64, Nat64) -> ();
regionStoreNat8 : (Region, Nat64, Nat8) -> ();
replyDeadline : () -> Nat64;
rts_callback_table_count : () -> Nat;
rts_callback_table_size : () -> Nat;
rts_collector_instructions : () -> Nat;
Expand Down
1 change: 1 addition & 0 deletions test/fail/ok/suggest-long-ai.tc.ok
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ suggest-long-ai.mo:4.1-4.5: type error [M0072], field stableM does not exist in
regionStoreNat32 : (Region, Nat64, Nat32) -> ();
regionStoreNat64 : (Region, Nat64, Nat64) -> ();
regionStoreNat8 : (Region, Nat64, Nat8) -> ();
replyDeadline : () -> Nat64;
rts_callback_table_count : () -> Nat;
rts_callback_table_size : () -> Nat;
rts_collector_instructions : () -> Nat;
Expand Down
1 change: 1 addition & 0 deletions test/fail/ok/suggest-short-ai.tc.ok
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ suggest-short-ai.mo:4.1-4.5: type error [M0072], field s does not exist in type:
regionStoreNat32 : (Region, Nat64, Nat32) -> ();
regionStoreNat64 : (Region, Nat64, Nat64) -> ();
regionStoreNat8 : (Region, Nat64, Nat8) -> ();
replyDeadline : () -> Nat64;
rts_callback_table_count : () -> Nat;
rts_callback_table_size : () -> Nat;
rts_collector_instructions : () -> Nat;
Expand Down
1 change: 1 addition & 0 deletions test/run-drun/composite-query.mo
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ actor Composites {
};

public composite query func cq1() : async () {
assert 0 : Nat64 == Prim.replyDeadline();
};

public composite query func cq2() : async () {
Expand Down
4 changes: 2 additions & 2 deletions test/run-drun/ok/composite-query.tc.ok
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
composite-query.mo:30.11-30.13: warning [M0145], this pattern of type
composite-query.mo:31.11-31.13: warning [M0145], this pattern of type
?Class__1
does not cover value
null
composite-query.mo:35.11-35.13: warning [M0145], this pattern of type
composite-query.mo:36.11-36.13: warning [M0145], this pattern of type
?Class__1
does not cover value
null
2 changes: 1 addition & 1 deletion test/run-drun/ok/query2.run-ir.ok
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ In read:
6
6
The following fails in the interpreter, for lack of query semantics
query2.mo:35.4-35.18: execution error, assertion failure
query2.mo:37.4-37.18: execution error, assertion failure
2 changes: 1 addition & 1 deletion test/run-drun/ok/query2.run-low.ok
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ In read:
6
6
The following fails in the interpreter, for lack of query semantics
query2.mo:35.4-35.18: execution error, assertion failure
query2.mo:37.4-37.18: execution error, assertion failure
2 changes: 1 addition & 1 deletion test/run-drun/ok/query2.run.ok
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ In read:
6
6
The following fails in the interpreter, for lack of query semantics
query2.mo:35.4-35.18: execution error, assertion failure
query2.mo:37.4-37.18: execution error, assertion failure
2 changes: 2 additions & 0 deletions test/run-drun/query2.mo
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ actor counter = {
Prim.debugPrintNat c;
};
public func printCounter () : async () {
assert 0 : Nat64 == Prim.replyDeadline();
Prim.debugPrintNat c;
};
public func get() : async Nat {
return c
};
public query func read() : async Nat {
assert 0 : Nat64 == Prim.replyDeadline();
let tmp = c;
c += 1;
Prim.debugPrint "In read:";
Expand Down
Loading