1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Asm.fif improvements (#631) (#645)

* Asm.fif improvements (#631)

Add missing opcodes, CUSTOMOP, disallow 256 PUSHPOW256, recursive PROGRAM, require-asm-fif-version

* Fix nested PROGRAM, add test

* Simplify require-asm-fif-version

---------

Co-authored-by: EmelyanenkoK <emelyanenko.kirill@gmail.com>
This commit is contained in:
SpyCheese 2023-03-13 13:48:48 +00:00 committed by GitHub
parent fbb1e548f7
commit 4d5ded5761
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 198 additions and 1 deletions

View file

@ -2,6 +2,8 @@ library TVM_Asm
// simple TVM Assembler // simple TVM Assembler
namespace Asm namespace Asm
Asm definitions Asm definitions
"0.4.3" constant asm-fif-version
variable @atend variable @atend
variable @was-split variable @was-split
false @was-split ! false @was-split !
@ -253,7 +255,7 @@ x{7F} @Defop TRUE
} cond } cond
} cond } cond
@addopb } dup : PUSHINT : INT @addopb } dup : PUSHINT : INT
{ <b x{83} s, swap 1- 8 u, @addopb } : PUSHPOW2 { dup 256 = abort"use PUSHNAN instead of 256 PUSHPOW2" <b x{83} s, swap 1- 8 u, @addopb } : PUSHPOW2
x{83FF} @Defop PUSHNAN x{83FF} @Defop PUSHNAN
{ <b x{84} s, swap 1- 8 u, @addopb } : PUSHPOW2DEC { <b x{84} s, swap 1- 8 u, @addopb } : PUSHPOW2DEC
{ <b x{85} s, swap 1- 8 u, @addopb } : PUSHNEGPOW2 { <b x{85} s, swap 1- 8 u, @addopb } : PUSHNEGPOW2
@ -326,38 +328,85 @@ x{A7} x{A8} @Defop(8i,alt) MULCONST
' SUBCONST : SUBINT ' SUBCONST : SUBINT
' MULCONST : MULINT ' MULCONST : MULINT
x{A8} @Defop MUL x{A8} @Defop MUL
x{A904} @Defop DIV x{A904} @Defop DIV
x{A905} @Defop DIVR x{A905} @Defop DIVR
x{A906} @Defop DIVC x{A906} @Defop DIVC
x{A908} @Defop MOD x{A908} @Defop MOD
x{A909} @Defop MODR
x{A90A} @Defop MODC
x{A90C} @Defop DIVMOD x{A90C} @Defop DIVMOD
x{A90D} @Defop DIVMODR x{A90D} @Defop DIVMODR
x{A90E} @Defop DIVMODC x{A90E} @Defop DIVMODC
x{A925} @Defop RSHIFTR x{A925} @Defop RSHIFTR
x{A926} @Defop RSHIFTC x{A926} @Defop RSHIFTC
x{A928} @Defop MODPOW2
x{A929} @Defop MODPOW2R
x{A92A} @Defop MODPOW2C
x{A92C} @Defop RSHIFTMOD
x{A92D} @Defop RSHIFTMODR
x{A92E} @Defop RSHIFTMODC
x{A935} @Defop(8u+1) RSHIFTR# x{A935} @Defop(8u+1) RSHIFTR#
x{A936} @Defop(8u+1) RSHIFTC# x{A936} @Defop(8u+1) RSHIFTC#
x{A938} @Defop(8u+1) MODPOW2# x{A938} @Defop(8u+1) MODPOW2#
x{A939} @Defop(8u+1) MODPOW2R# x{A939} @Defop(8u+1) MODPOW2R#
x{A93A} @Defop(8u+1) MODPOW2C# x{A93A} @Defop(8u+1) MODPOW2C#
x{A93C} @Defop(8u+1) RSHIFT#MOD
x{A93D} @Defop(8u+1) RSHIFTR#MOD
x{A93E} @Defop(8u+1) RSHIFTC#MOD
x{A984} @Defop MULDIV x{A984} @Defop MULDIV
x{A985} @Defop MULDIVR x{A985} @Defop MULDIVR
x{A986} @Defop MULDIVC
x{A988} @Defop MULMOD x{A988} @Defop MULMOD
x{A989} @Defop MULMODR
x{A98A} @Defop MULMODC
x{A98C} @Defop MULDIVMOD x{A98C} @Defop MULDIVMOD
x{A98D} @Defop MULDIVMODR x{A98D} @Defop MULDIVMODR
x{A98E} @Defop MULDIVMODC x{A98E} @Defop MULDIVMODC
x{A9A4} @Defop MULRSHIFT x{A9A4} @Defop MULRSHIFT
x{A9A5} @Defop MULRSHIFTR x{A9A5} @Defop MULRSHIFTR
x{A9A6} @Defop MULRSHIFTC x{A9A6} @Defop MULRSHIFTC
x{A9A8} @Defop MULMODPOW2
x{A9A9} @Defop MULMODPOW2R
x{A9AA} @Defop MULMODPOW2C
x{A9AC} @Defop MULRSHIFTMOD
x{A9AD} @Defop MULRSHIFTRMOD
x{A9AE} @Defop MULRSHIFTCMOD
x{A9B4} @Defop(8u+1) MULRSHIFT# x{A9B4} @Defop(8u+1) MULRSHIFT#
x{A9B5} @Defop(8u+1) MULRSHIFTR# x{A9B5} @Defop(8u+1) MULRSHIFTR#
x{A9B6} @Defop(8u+1) MULRSHIFTC# x{A9B6} @Defop(8u+1) MULRSHIFTC#
x{A9B8} @Defop(8u+1) MULMODPOW2#
x{A9B9} @Defop(8u+1) MULMODPOW2R#
x{A9BA} @Defop(8u+1) MULMODPOW2C#
x{A9BC} @Defop(8u+1) MULRSHIFT#MOD
x{A9BD} @Defop(8u+1) MULRSHIFTR#MOD
x{A9BE} @Defop(8u+1) MULRSHIFTC#MOD
x{A9C4} @Defop LSHIFTDIV x{A9C4} @Defop LSHIFTDIV
x{A9C5} @Defop LSHIFTDIVR x{A9C5} @Defop LSHIFTDIVR
x{A9C6} @Defop LSHIFTDIVC x{A9C6} @Defop LSHIFTDIVC
x{A9C8} @Defop LSHIFTMOD
x{A9C9} @Defop LSHIFTMODR
x{A9CA} @Defop LSHIFTMODC
x{A9CC} @Defop LSHIFTDIVMOD
x{A9CD} @Defop LSHIFTDIVMODR
x{A9CE} @Defop LSHIFTDIVMODC
x{A9D4} @Defop(8u+1) LSHIFT#DIV x{A9D4} @Defop(8u+1) LSHIFT#DIV
x{A9D5} @Defop(8u+1) LSHIFT#DIVR x{A9D5} @Defop(8u+1) LSHIFT#DIVR
x{A9D6} @Defop(8u+1) LSHIFT#DIVC x{A9D6} @Defop(8u+1) LSHIFT#DIVC
x{A9D8} @Defop(8u+1) LSHIFT#MOD
x{A9D9} @Defop(8u+1) LSHIFT#MODR
x{A9DA} @Defop(8u+1) LSHIFT#MODC
x{A9DC} @Defop(8u+1) LSHIFT#DIVMOD
x{A9DD} @Defop(8u+1) LSHIFT#DIVMODR
x{A9DE} @Defop(8u+1) LSHIFT#DIVMODC
x{AA} @Defop(8u+1) LSHIFT# x{AA} @Defop(8u+1) LSHIFT#
x{AB} @Defop(8u+1) RSHIFT# x{AB} @Defop(8u+1) RSHIFT#
x{AC} @Defop LSHIFT x{AC} @Defop LSHIFT
@ -506,6 +555,7 @@ x{CF1E} @Defop STSLICERQ
x{CF1F} dup @Defop STBRQ @Defop BCONCATQ x{CF1F} dup @Defop STBRQ @Defop BCONCATQ
x{CF20} @Defop(ref) STREFCONST x{CF20} @Defop(ref) STREFCONST
{ <b x{CF21} s, rot ref, swap ref, @addopb } : STREF2CONST { <b x{CF21} s, rot ref, swap ref, @addopb } : STREF2CONST
x{CF23} @Defop ENDXC
x{CF28} @Defop STILE4 x{CF28} @Defop STILE4
x{CF29} @Defop STULE4 x{CF29} @Defop STULE4
x{CF2A} @Defop STILE8 x{CF2A} @Defop STILE8
@ -608,6 +658,9 @@ x{D733} @Defop SSKIPLAST
x{D734} @Defop SUBSLICE x{D734} @Defop SUBSLICE
x{D736} @Defop SPLIT x{D736} @Defop SPLIT
x{D737} @Defop SPLITQ x{D737} @Defop SPLITQ
x{D739} @Defop XCTOS
x{D73A} @Defop XLOAD
x{D73B} @Defop XLOADQ
x{D741} @Defop SCHKBITS x{D741} @Defop SCHKBITS
x{D742} @Defop SCHKREFS x{D742} @Defop SCHKREFS
x{D743} @Defop SCHKBITREFS x{D743} @Defop SCHKBITREFS
@ -1194,6 +1247,8 @@ x{FFF0} @Defop SETCPX
255 and <b x{FF} s, swap 8 u, @addopb 255 and <b x{FF} s, swap 8 u, @addopb
} : SETCP } : SETCP
' @addop : CUSTOMOP
// //
// provisions for defining programs consisting of several mutually-recursive procedures // provisions for defining programs consisting of several mutually-recursive procedures
// //
@ -1202,6 +1257,7 @@ variable @proclist
variable @procdict variable @procdict
variable @procinfo variable @procinfo
variable @gvarcnt variable @gvarcnt
variable @parent-state
variable asm-mode 1 asm-mode ! variable asm-mode 1 asm-mode !
19 constant @procdictkeylen 19 constant @procdictkeylen
32 constant @zcount 32 constant @zcount
@ -1224,6 +1280,9 @@ variable asm-mode 1 asm-mode !
variable @oldcurrent variable @oldctx variable @oldcurrent variable @oldctx
Fift-wordlist dup @oldcurrent ! @oldctx ! Fift-wordlist dup @oldcurrent ! @oldctx !
{ current@ @oldcurrent ! context@ @oldctx ! Asm definitions { current@ @oldcurrent ! context@ @oldctx ! Asm definitions
@proccnt @ @proclist @ @procdict @ @procinfo @ @gvarcnt @ @parent-state @ current@ @oldcurrent @ @oldctx @
9 tuple @parent-state !
hole current!
0 =: main @proclist null! @proccnt 0! @gvarcnt 0! 0 =: main @proclist null! @proccnt 0! @gvarcnt 0!
{ bl word @newproc } : NEWPROC { bl word @newproc } : NEWPROC
{ bl word dup (def?) ' drop ' @newproc cond } : DECLPROC { bl word dup (def?) ' drop ' @newproc cond } : DECLPROC
@ -1298,6 +1357,10 @@ Fift-wordlist dup @oldcurrent ! @oldctx !
} while } while
drop @proclist null! @procinfo null! @proccnt 0! drop @proclist null! @procinfo null! @proccnt 0!
@procdict dup @ swap null! @procdict dup @ swap null!
@parent-state @ dup null? { drop } {
9 untuple
@oldctx ! @oldcurrent ! current! @parent-state ! @gvarcnt ! @procinfo ! @procdict ! @proclist ! @proccnt !
} cond
@oldctx @ context! @oldcurrent @ current! @oldctx @ context! @oldcurrent @ current!
} : }END } : }END
forget @proclist forget @proccnt forget @proclist forget @proccnt
@ -1326,7 +1389,43 @@ forget @proclist forget @proccnt
// ( c -- c' ) // ( c -- c' )
{ hash hash>libref } : >libref { hash hash>libref } : >libref
{ dup "." $pos dup -1 =
{ drop 0 }
{ $| 1 $| nip swap (number) 1- abort"invalid version"
dup dup 0 < swap 999 > or abort"invalid version"
}
cond
} : parse-version-level
{
0 swap
"." $+
{ swap 1000 * swap parse-version-level rot + swap } 3 times
"" $= not abort"invalid version"
} : parse-asm-fif-version
{
dup =: required-version parse-asm-fif-version
asm-fif-version parse-asm-fif-version
= 1+ {
"Required Asm.fif version: " @' required-version "; actual Asm.fif version: " asm-fif-version $+ $+ $+ abort
} if
} : require-asm-fif-version
{
dup =: required-version parse-asm-fif-version
asm-fif-version parse-asm-fif-version
swap
>= 1+ {
"Required Asm.fif version: " @' required-version "; actual Asm.fif version: " asm-fif-version $+ $+ $+ abort
} if
} : require-asm-fif-version>=
Fift definitions Asm Fift definitions Asm
' <{ : <{ ' <{ : <{
' PROGRAM{ : PROGRAM{ ' PROGRAM{ : PROGRAM{
' asm-fif-version : asm-fif-version
' require-asm-fif-version : require-asm-fif-version
' require-asm-fif-version>= : require-asm-fif-version>=
Fift Fift

View file

@ -126,3 +126,7 @@ TEST(Fift, test_fiftext) {
TEST(Fift, test_namespaces) { TEST(Fift, test_namespaces) {
run_fift("namespaces.fif"); run_fift("namespaces.fif");
} }
TEST(Fift, test_asm_nested_program) {
run_fift("asm-nested-program.fif");
}

View file

@ -0,0 +1,93 @@
"Asm.fif" include
// Four programs:
// 4 contains 2 and 3, 2 contains 1
// Program #1
PROGRAM{
DECLPROC foo1
DECLPROC foo2
DECLPROC foo3
DECLPROC main
foo1 PROC:<{ MUL INC }>
foo2 PROCINLINE:<{ PLDREF }>
foo3 PROC:<{ CTOS foo2 INLINECALLDICT CTOS 32 PLDU }>
main PROC:<{ 0 PUSHINT }>
}END>c constant code-1
// Program #2
PROGRAM{
DECLPROC foo3
DECLPROC foo4
DECLPROC main
foo3 PROC:<{ code-1 PUSHREF }>
foo4 PROC:<{ CTOS 8 PLDU }>
main PROC:<{ foo3 CALLDICT foo4 CALLDICT NEWC ROT STUX }>
}END>c constant code-2
// Program #3
PROGRAM{
DECLPROC foo1
DECLPROC foo4
DECLPROC main
foo1 PROC:<{ DUP 137 PUSHINT MUL PAIR }>
foo4 PROC:<{ UNPAIR SWAP DIV }>
main PROC:<{ 70 PUSHINT DIV }>
}END>c constant code-3
// Program #4
PROGRAM{
DECLPROC foo2
DECLPROC foo3
DECLPROC foo5
DECLPROC main
foo2 PROC:<{ code-2 PUSHREF }>
foo3 PROC:<{ code-3 PUSHREF }>
foo5 PROC:<{ foo2 CALLDICT CTOS 8 PLDU 1 RSHIFT# }>
main PROC:<{ foo5 CALLDICT 5 MULCONST }>
}END>c
.dump cr
// Program #4, nested
PROGRAM{
DECLPROC foo2
DECLPROC foo3
DECLPROC foo5
DECLPROC main
foo2 PROC:<{
PROGRAM{
DECLPROC foo3
DECLPROC foo4
DECLPROC main
foo3 PROC:<{
PROGRAM{
DECLPROC foo1
DECLPROC foo2
DECLPROC foo3
DECLPROC main
foo1 PROC:<{ MUL INC }>
foo2 PROCINLINE:<{ PLDREF }>
foo3 PROC:<{ CTOS foo2 INLINECALLDICT CTOS 32 PLDU }>
main PROC:<{ 0 PUSHINT }>
}END>c PUSHREF
}>
foo4 PROC:<{ CTOS 8 PLDU }>
main PROC:<{ foo3 CALLDICT foo4 CALLDICT NEWC ROT STUX }>
}END>c PUSHREF
}>
foo3 PROC:<{
PROGRAM{
DECLPROC foo1
DECLPROC foo4
DECLPROC main
foo1 PROC:<{ DUP 137 PUSHINT MUL PAIR }>
foo4 PROC:<{ UNPAIR SWAP DIV }>
main PROC:<{ 70 PUSHINT DIV }>
}END>c PUSHREF
}>
foo5 PROC:<{ foo2 CALLDICT CTOS 8 PLDU 1 RSHIFT# }>
main PROC:<{ foo5 CALLDICT 5 MULCONST }>
}END>c
.dump cr

View file

@ -6,6 +6,7 @@ Test_Fift_bug_div_default 1ac42861ce96b2896001c587f65e9afe1617db48859f19c2f4e306
Test_Fift_bug_newlize_default e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 Test_Fift_bug_newlize_default e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Test_Fift_bug_ufits_default 51bf5a9f1ed7633a193f6fdd17a7a3af8e032dfe72a9669c85e8639aa8a7c195 Test_Fift_bug_ufits_default 51bf5a9f1ed7633a193f6fdd17a7a3af8e032dfe72a9669c85e8639aa8a7c195
Test_Fift_contfrac_default 09ebce5c91bcb70696c6fb6981d82dc3b9e3444dab608a7a1b044c0ddd778a96 Test_Fift_contfrac_default 09ebce5c91bcb70696c6fb6981d82dc3b9e3444dab608a7a1b044c0ddd778a96
Test_Fift_test_asm_nested_program_default 2a19decac67adb719c444ab42879a5d894447d450d1998848c469605531076ad
Test_Fift_test_default 4e44b3382963ec89f7b5c8f2ebd85da3bc8aebad5b49f5b11b14075061477b4d Test_Fift_test_default 4e44b3382963ec89f7b5c8f2ebd85da3bc8aebad5b49f5b11b14075061477b4d
Test_Fift_test_dict_default a9c8cbcfdece5573185022cea07f59f1bc404e5d879e5157a5745757f8ee0525 Test_Fift_test_dict_default a9c8cbcfdece5573185022cea07f59f1bc404e5d879e5157a5745757f8ee0525
Test_Fift_test_disasm_default dacaa555f5f217b2373e01e3bcd59634e480f5759dcc43edbdef35273ae38492 Test_Fift_test_disasm_default dacaa555f5f217b2373e01e3bcd59634e480f5759dcc43edbdef35273ae38492