From de570873d7f62c0a82df3916375dd7398790551b Mon Sep 17 00:00:00 2001 From: Aleksandr Kirsanov Date: Wed, 8 May 2024 13:24:11 +0300 Subject: [PATCH] [FunC] Add builtin functions to stdlib.fc Note, that I have not added all builtin functions. I filtered out strange and actually unused in practice, like "int_at()" and similar, or "run_method0()" and similar. (Probably, they should be dropped off even from builtins) Also, I've modified some stdlib.fc legacy tests just to ensure that a resulting hash doesn't change. --- .../bsc-bridge-collector/stdlib.fc | 35 ++++++-- .../auto-tests/legacy_tests/config/stdlib.fc | 35 ++++++-- .../legacy_tests/dns-collection/stdlib.fc | 35 ++++++-- .../auto-tests/legacy_tests/elector/stdlib.fc | 35 ++++++-- .../eth-bridge-multisig/stdlib.fc | 35 ++++++-- .../legacy_tests/gg-marketplace/stdlib.fc | 37 +++++--- .../jetton-minter/imports/stdlib.fc | 35 ++++++-- .../jetton-wallet/imports/stdlib.fc | 35 ++++++-- .../legacy_tests/nft-collection/stdlib.fc | 37 +++++--- crypto/smartcont/stdlib.fc | 89 +++++++++++++++---- 10 files changed, 307 insertions(+), 101 deletions(-) diff --git a/crypto/func/auto-tests/legacy_tests/bsc-bridge-collector/stdlib.fc b/crypto/func/auto-tests/legacy_tests/bsc-bridge-collector/stdlib.fc index b168d558..3fac94f1 100644 --- a/crypto/func/auto-tests/legacy_tests/bsc-bridge-collector/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/bsc-bridge-collector/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -// () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -// (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -// (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -// int preload_int(slice s, int len) pure asm "PLDIX"; -// int preload_uint(slice s, int len) pure asm "PLDUX"; -// (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -// slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -// builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -// builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/config/stdlib.fc b/crypto/func/auto-tests/legacy_tests/config/stdlib.fc index 5614d76f..f85fd907 100644 --- a/crypto/func/auto-tests/legacy_tests/config/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/config/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/dns-collection/stdlib.fc b/crypto/func/auto-tests/legacy_tests/dns-collection/stdlib.fc index aaa71720..f0721815 100644 --- a/crypto/func/auto-tests/legacy_tests/dns-collection/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/dns-collection/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/elector/stdlib.fc b/crypto/func/auto-tests/legacy_tests/elector/stdlib.fc index 8d0224d0..49af552b 100644 --- a/crypto/func/auto-tests/legacy_tests/elector/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/elector/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -// () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -// (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -// (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -// int preload_int(slice s, int len) pure asm "PLDIX"; -// int preload_uint(slice s, int len) pure asm "PLDUX"; -// (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -// slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -// builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -// builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/eth-bridge-multisig/stdlib.fc b/crypto/func/auto-tests/legacy_tests/eth-bridge-multisig/stdlib.fc index 15d7bcbe..9fb900c5 100644 --- a/crypto/func/auto-tests/legacy_tests/eth-bridge-multisig/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/eth-bridge-multisig/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/gg-marketplace/stdlib.fc b/crypto/func/auto-tests/legacy_tests/gg-marketplace/stdlib.fc index f4b671bd..ddcb2396 100644 --- a/crypto/func/auto-tests/legacy_tests/gg-marketplace/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/gg-marketplace/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -108,9 +125,9 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; - builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_ref(builder b, cell c) pure asm(c b) "STREF"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/jetton-minter/imports/stdlib.fc b/crypto/func/auto-tests/legacy_tests/jetton-minter/imports/stdlib.fc index a76e869d..ddcb2396 100644 --- a/crypto/func/auto-tests/legacy_tests/jetton-minter/imports/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/jetton-minter/imports/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/jetton-wallet/imports/stdlib.fc b/crypto/func/auto-tests/legacy_tests/jetton-wallet/imports/stdlib.fc index a76e869d..ddcb2396 100644 --- a/crypto/func/auto-tests/legacy_tests/jetton-wallet/imports/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/jetton-wallet/imports/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -109,8 +126,8 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/func/auto-tests/legacy_tests/nft-collection/stdlib.fc b/crypto/func/auto-tests/legacy_tests/nft-collection/stdlib.fc index f4b671bd..ddcb2396 100644 --- a/crypto/func/auto-tests/legacy_tests/nft-collection/stdlib.fc +++ b/crypto/func/auto-tests/legacy_tests/nft-collection/stdlib.fc @@ -21,12 +21,16 @@ forall X -> X first(tuple t) pure asm "FIRST"; forall X -> X second(tuple t) pure asm "SECOND"; forall X -> X third(tuple t) pure asm "THIRD"; forall X -> X fourth(tuple t) pure asm "3 INDEX"; +forall X -> X at(tuple t, int index) pure builtin; forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; forall X, Y -> Y pair_second([X, Y] p) pure asm "SECOND"; forall X, Y, Z -> X triple_first([X, Y, Z] p) pure asm "FIRST"; forall X, Y, Z -> Y triple_second([X, Y, Z] p) pure asm "SECOND"; forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; forall X -> X null() pure asm "PUSHNULL"; +forall X -> int null?(X x) pure builtin; +forall X -> X touch(X x) pure builtin; +forall X -> (X, ()) ~touch(X x) pure builtin; forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; int now() pure asm "NOW"; @@ -47,8 +51,15 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " (int, int, int, int) compute_data_size?(cell c, int max_cells) pure asm "CDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; (int, int, int, int) slice_compute_data_size?(cell c, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -;; () throw_if(int excno, int cond) asm "THROWARGIF"; +() throw(int excno) builtin; +() throw_if(int excno, int cond) builtin; +() throw_unless(int excno, int cond) builtin; +forall X -> () throw_arg(X x, int excno) builtin; +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; +forall X -> (X, ()) ~dump(X x) builtin; +forall X -> (X, ()) ~strdump(X x) builtin; () dump_stack() asm "DUMPSTK"; cell get_data() pure asm "c4 PUSH"; @@ -66,17 +77,23 @@ int min(int x, int y) pure asm "MIN"; int max(int x, int y) pure asm "MAX"; (int, int) minmax(int x, int y) pure asm "MINMAX"; int abs(int x) pure asm "ABS"; +(int, int) divmod(int x, int y) pure builtin; +(int, int) moddiv(int x, int y) pure builtin; +int muldiv(int x, int y, int z) pure builtin; +int muldivr(int x, int y, int z) pure builtin; +int muldivc(int x, int y, int z) pure builtin; +(int, int) muldivmod(int x, int y, int z) pure builtin; slice begin_parse(cell c) pure asm "CTOS"; () end_parse(slice s) asm "ENDS"; (slice, cell) load_ref(slice s) pure asm( -> 1 0) "LDREF"; cell preload_ref(slice s) pure asm "PLDREF"; -;; (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; -;; (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; -;; int preload_int(slice s, int len) pure asm "PLDIX"; -;; int preload_uint(slice s, int len) pure asm "PLDUX"; -;; (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; -;; slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +(slice, int) load_int(slice s, int len) pure builtin; +(slice, int) load_uint(slice s, int len) pure builtin; +int preload_int(slice s, int len) pure builtin; +int preload_uint(slice s, int len) pure builtin; +(slice, slice) load_bits(slice s, int len) pure builtin; +slice preload_bits(slice s, int len) pure builtin; (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; slice skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; (slice, ()) ~skip_bits(slice s, int len) pure asm "SDSKIPFIRST"; @@ -108,9 +125,9 @@ int builder_depth(builder b) pure asm "BDEPTH"; builder begin_cell() pure asm "NEWC"; cell end_cell(builder b) pure asm "ENDC"; - builder store_ref(builder b, cell c) pure asm(c b) "STREF"; -;; builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; -;; builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +builder store_ref(builder b, cell c) pure asm(c b) "STREF"; +builder store_uint(builder b, int x, int len) pure builtin; +builder store_int(builder b, int x, int len) pure builtin; builder store_slice(builder b, slice s) pure asm "STSLICER"; builder store_grams(builder b, int x) pure asm "STGRAMS"; builder store_dict(builder b, cell c) pure asm(c b) "STDICT"; diff --git a/crypto/smartcont/stdlib.fc b/crypto/smartcont/stdlib.fc index 9540603a..bf6d738b 100644 --- a/crypto/smartcont/stdlib.fc +++ b/crypto/smartcont/stdlib.fc @@ -93,6 +93,9 @@ forall X -> X third(tuple t) pure asm "THIRD"; /// Returns the fourth element of a tuple (with unknown element types). forall X -> X fourth(tuple t) pure asm "3 INDEX"; +/// Returns the [`index`]-th element of tuple [`t`]. +forall X -> X at(tuple t, int index) pure builtin; + /// Returns the first element of a pair tuple. forall X, Y -> X pair_first([X, Y] p) pure asm "FIRST"; @@ -114,7 +117,16 @@ forall X, Y, Z -> Z triple_third([X, Y, Z] p) pure asm "THIRD"; /// So `null` can actually have any atomic type. forall X -> X null() pure asm "PUSHNULL"; -/// Moves a variable [x] to the top of the stack +/// Checks whether the argument is null. +forall X -> int null?(X x) pure builtin; + +/// Moves a variable [x] to the top of the stack. +forall X -> X touch(X x) pure builtin; + +/// Moves a variable [x] to the top of the stack. +forall X -> (X, ()) ~touch(X x) pure builtin; + +/// Mark a variable as used, such that the code which produced it won't be deleted even if it is not impure. forall X -> (X, ()) ~impure_touch(X x) asm "NOP"; @@ -199,13 +211,38 @@ int check_data_signature(slice data, slice signature, int public_key) pure asm " /// however, the data bits and the cell references of [s] are accounted for in `y` and `z`. (int, int, int, int) slice_compute_data_size?(slice s, int max_cells) pure asm "SDATASIZEQ NULLSWAPIFNOT2 NULLSWAPIFNOT"; -/// Throws an exception with exit_code excno if cond is not 0 (commented since implemented in compilator) -// () throw_if(int excno, int cond) asm "THROWARGIF"; +/// Throws exception [`excno`] with parameter zero. +/// In other words, it transfers control to the continuation in `c2`, +/// pushing `0` and [`excno`] into it's stack, and discarding the old stack altogether. +() throw(int excno) builtin; + +/// Throws exception [`excno`] with parameter zero only if [`cond`] != `0`. +() throw_if(int excno, int cond) builtin; + +/// Throws exception [`excno`] with parameter zero only if [`cond`] == `0`. +() throw_unless(int excno, int cond) builtin; + +/// Throws exception [`excno`] with parameter [`x`], +/// by copying [`x`] and [`excno`] into the stack of `c2` and transferring control to `c2`. +forall X -> () throw_arg(X x, int excno) builtin; + +/// Throws exception [`excno`] with parameter [`x`] only if [`cond`] != `0`. +forall X -> () throw_arg_if(X x, int excno, int cond) builtin; + +/// Throws exception [`excno`] with parameter [`x`] only if [`cond`] == `0`. +forall X -> () throw_arg_unless(X x, int excno, int cond) builtin; /*** # Debug primitives Only works for local TVM execution with debug level verbosity */ + +/// Dump a variable [x] to the debug log. +forall X -> (X, ()) ~dump(X x) builtin; + +/// Dump a string [x] to the debug log. +forall X -> (X, ()) ~strdump(X x) builtin; + /// Dumps the stack (at most the top 255 values) and shows the total stack depth. () dump_stack() asm "DUMPSTK"; @@ -277,6 +314,25 @@ int max(int x, int y) pure asm "MAX"; /// Computes the absolute value of an integer [x]. int abs(int x) pure asm "ABS"; +/// Computes the quotient and remainder of [x] / [y]. Example: divmod(112,3) = (37,1) +(int, int) divmod(int x, int y) pure builtin; + +/// Computes the remainder and quotient of [x] / [y]. Example: moddiv(112,3) = (1,37) +(int, int) moddiv(int x, int y) pure builtin; + +/// Computes multiple-then-divide: floor([x] * [y] / [z]). +/// The intermediate result is stored in a 513-bit integer to prevent precision loss. +int muldiv(int x, int y, int z) pure builtin; + +/// Similar to `muldiv`, but rounds the result: round([x] * [y] / [z]). +int muldivr(int x, int y, int z) pure builtin; + +/// Similar to `muldiv`, but ceils the result: ceil([x] * [y] / [z]). +int muldivc(int x, int y, int z) pure builtin; + +/// Computes the quotient and remainder of ([x] * [y] / [z]). Example: muldivmod(112,3,10) = (33,6) +(int, int) muldivmod(int x, int y, int z) pure builtin; + /* # Slice primitives @@ -305,25 +361,23 @@ slice begin_parse(cell c) pure asm "CTOS"; /// Preloads the first reference from the slice. cell preload_ref(slice s) pure asm "PLDREF"; - /* Functions below are commented because are implemented on compilator level for optimisation */ - /// Loads a signed [len]-bit integer from a slice [s]. -// (slice, int) ~load_int(slice s, int len) pure asm(s len -> 1 0) "LDIX"; +(slice, int) load_int(slice s, int len) pure builtin; /// Loads an unsigned [len]-bit integer from a slice [s]. -// (slice, int) ~load_uint(slice s, int len) pure asm( -> 1 0) "LDUX"; +(slice, int) load_uint(slice s, int len) pure builtin; /// Preloads a signed [len]-bit integer from a slice [s]. -// int preload_int(slice s, int len) pure asm "PLDIX"; +int preload_int(slice s, int len) pure builtin; /// Preloads an unsigned [len]-bit integer from a slice [s]. -// int preload_uint(slice s, int len) pure asm "PLDUX"; +int preload_uint(slice s, int len) pure builtin; -/// Loads the first `0 ≤ len ≤ 1023` bits from slice [s] into a separate `slice s''`. -// (slice, slice) load_bits(slice s, int len) pure asm(s len -> 1 0) "LDSLICEX"; +/// Loads the first `0 ≤ len ≤ 1023` bits from slice [s] into a separate slice `s''`. +(slice, slice) load_bits(slice s, int len) pure builtin; -/// Preloads the first `0 ≤ len ≤ 1023` bits from slice [s] into a separate `slice s''`. -// slice preload_bits(slice s, int len) pure asm "PLDSLICEX"; +/// Preloads the first `0 ≤ len ≤ 1023` bits from slice [s] into a separate slice `s''`. +slice preload_bits(slice s, int len) pure builtin; /// Loads serialized amount of TonCoins (any unsigned integer up to `2^120 - 1`). (slice, int) load_grams(slice s) pure asm( -> 1 0) "LDGRAMS"; @@ -432,13 +486,12 @@ cell end_cell(builder b) pure asm "ENDC"; builder store_ref(builder b, cell c) pure asm(c b) "STREF"; /// Stores an unsigned [len]-bit integer `x` into `b` for `0 ≤ len ≤ 256`. -// builder store_uint(builder b, int x, int len) pure asm(x b len) "STUX"; +builder store_uint(builder b, int x, int len) pure builtin; -/// Stores a signed [len]-bit integer `x` into `b` for` 0 ≤ len ≤ 257`. -// builder store_int(builder b, int x, int len) pure asm(x b len) "STIX"; +/// Stores a signed [len]-bit integer `x` into `b` for `0 ≤ len ≤ 257`. +builder store_int(builder b, int x, int len) pure builtin; - -/// Stores `slice` [s] into `builder` [b] +/// Stores `slice` [s] into `builder` [b]. builder store_slice(builder b, slice s) pure asm "STSLICER"; /// Stores (serializes) an integer [x] in the range `0..2^120 − 1` into `builder` [b].