Commit graph

190 commits

Author SHA1 Message Date
Roman Khimov
e1d3223505
Merge pull request #1247 from nspcc-dev/feature/pointers
Support pointers in compiler
2020-08-06 13:53:08 +03:00
Evgenii Stratonikov
f2107bfbc4 compiler: copy structs when passing as arguments
In Go structs must be copied when used as arguments.
To do so we must clone struct on VM level.
This is done by appending this struct to an intermediate array.
2020-08-05 13:14:38 +03:00
Evgenii Stratonikov
4488f61777 compiler: compile init even if there are no globals
`init` can be useful even if no globals are present,
e.g. we can use some syscall inside.
2020-08-05 12:59:53 +03:00
Evgenii Stratonikov
6f2759be3a compiler: process packages in deterministic order 2020-08-05 11:00:25 +03:00
Evgenii Stratonikov
b771d2d024 compiler: allow to use init function
Process `init()` functions after global variables has been processed.
It's body is saved into the `_initialize` method where all
initialization is performed.
2020-08-05 11:00:25 +03:00
Evgenii Stratonikov
d54c60ded3 compiler: support pointer dereferencing for structs
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-08-04 11:14:07 +03:00
Evgenii Stratonikov
eb047b12a7 compiler: support creating pointers to struct
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-08-04 11:14:07 +03:00
Evgenii Stratonikov
a781d299e0 compiler: use fully-qualified names for tracking functions
Function name now consists of 3 parts:
1) full package path
2) method receiver type (if any)
3) function name itself .

Fix #1150.

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-31 12:07:06 +03:00
Evgenii Stratonikov
528c184f00 compiler: allow to use exported constants
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-31 12:06:42 +03:00
Evgenii Stratonikov
6df019913d compiler: allow to use exported variables
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-31 12:06:42 +03:00
Evgenii Stratonikov
b8d7e93459 compiler: make ForEachFile accept a package
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-31 12:06:42 +03:00
Evgenii Stratonikov
7009417325 compiler: allow to declare global variables in multiple files
Traverse and count globals across all used files.

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
2020-07-31 12:06:42 +03:00
Evgenii Stratonikov
685d44dbc1 *: support _initialize method in contracts
Invoke `_initialize` method on every call if present.
In NEO3 there is no entrypoint and methods are invoked by offset,
thus `Main` function is no longer required.
We still have special `Main` method in tests to simplify them.
2020-07-27 13:00:35 +03:00
Evgenii Stratonikov
d2ddf7b7cb *: support invoking methods by offset
Allow to invoke methods by offset:
1. Every invoked contract must have manifest.
2. Check arguments count on invocation.
3. Change AppCall to a regular syscall.
4. Add test suite for `System.Contract.Call`.
2020-07-27 13:00:35 +03:00
Evgenii Stratonikov
e87eba51f9 compiler: emit bytecode for unused exported functions
Exported functions should always be present in byte-code.
This will be needed later when arbitrary method calls are allowed.
2020-07-27 13:00:35 +03:00
Roman Khimov
2800179ce0
Merge pull request #1226 from nspcc-dev/fix/pusha
vm: make offset in PUSHA relative
2020-07-23 23:40:21 +03:00
Evgenii Stratonikov
b8843a2dfa vm: make offset in PUSHA relative
Follow neo-project/neo-vm#317 .
2020-07-23 13:07:30 +03:00
Anna Shaleva
2bbe218547 compiler: move SHA256 from builtins to syscalls
Now it can be processed as a normal syscall.
2020-07-22 16:58:32 +03:00
Anna Shaleva
a1f98f92fe compiler: add ConvertResultToStruct flag
Part of #1055.

There'll be a lot of interops which result with a struct on stack instead
of interop interface, and sometimes their names are the same, so it's
unrelyable to take into account interop name only and don't pay
attention to it's API (package).

Also sort syscalls by package and name.
2020-07-17 08:19:43 +03:00
Anna Shaleva
c4f7b06974 core, compiler: return struct from GetScriptContainer interop
Closes #1173
2020-07-14 06:04:48 +03:00
Roman Khimov
bc1d6791b9 compiler: allow to append multiple elements 2020-07-09 13:59:43 +03:00
Roman Khimov
76925fe3e0 compiler: slices must default to nil 2020-07-09 13:07:21 +03:00
Roman Khimov
eee8ac1655 compiler: fix initialization of struct fields, fix #1164
Make `s{}` initializers work. Deduplicate code a bit along the way. The test
added follows bf6aa02dcf test.
2020-07-09 12:27:21 +03:00
Anna Shaleva
56a5c9db11 compiler: compile appcall with dynamic argument
Closes #1160
2020-07-08 19:49:14 +03:00
Roman Khimov
ebe37d1a46 compiler: check for NULL when calculating len(), fix #1153 2020-07-07 21:49:21 +03:00
Anna Shaleva
c3a0998cae compiler: fix bug in codegen
Main function (as far as the others uncknown to codegen at the moment of
`convertFuncDecl`) didn't have package set. Fixed.
2020-07-07 13:28:38 +03:00
Evgenii Stratonikov
26cfae7c9a compiler: support shadowing via Block statements 2020-06-30 10:31:52 +03:00
Evgenii Stratonikov
40bacc6775 compiler: support variable shadowing
Closes #1131.
2020-06-30 10:31:52 +03:00
Evgenii Stratonikov
1ee4acbdbc compiler: manage variables in a separate varScope struct
Abstract var scope management from the funcScope.
2020-06-30 10:31:51 +03:00
Evgenii Stratonikov
057e1e2806 compiler: support ... variadic calls 2020-06-27 10:42:30 +03:00
Evgenii Stratonikov
a88ac44147 compiler: support variadic function definitions
Pack variadic arguments into a slice. This currently doen't work with
byte slices though.
2020-06-26 20:05:10 +03:00
Roman Khimov
9ca87855a6
Merge pull request #1101 from nspcc-dev/feature/convert
Support type conversions
2020-06-25 18:30:03 +03:00
Evgenii Stratonikov
6ddaed3927 compiler: allow to omit struct field names in literals 2020-06-24 19:33:58 +03:00
Evgenii Stratonikov
5a615d8178 compiler: allow to omit types for nested slices 2020-06-24 19:25:08 +03:00
Evgenii Stratonikov
2c5ab95b8a compiler: convert to ByteArray for string variables
Convert to ByteArray when converting variable to `string`, because
underlying byte-slice changes should not affect result string.
2020-06-24 18:59:36 +03:00
Evgenii Stratonikov
1d275ceb65 compiler: distinguish between type conversions and function calls
RN every identifier in call expression is considered to be lambda.
But it also can be type expression, so we need to distinguish between
these cases.
2020-06-24 18:46:32 +03:00
Roman Khimov
53f2e130c0
Merge pull request #1100 from nspcc-dev/neo3/compiler/dbgjson
compiler: update debug.json format
2020-06-24 18:35:08 +03:00
Evgenii Stratonikov
904b2136fc compiler: emit CONVERT opcode for type assertions
Emit CONVERT for converting between different types. NeoVM behavior is
different from that of Go (e.g. assertions of `int` and `uint32` are
equivalent).
2020-06-24 18:00:26 +03:00
Anna Shaleva
4d07d72677 compiler: add Hash to debug info
part of #1088
2020-06-24 16:50:34 +03:00
Roman Khimov
954c8ff8d6 compiler: support nil checks 2020-06-24 10:43:58 +03:00
Evgenii Stratonikov
e54149d547 compiler: do not load map key twice in for-range loop 2020-06-22 13:43:59 +03:00
Evgenii Stratonikov
1847c28b42 compiler: do not load values which will be dropped 2020-06-22 13:43:59 +03:00
Evgenii Stratonikov
72be5412f4 compiler: optimize argument reversing
Do not reverse arguments if there is no more than 1.
2020-06-22 13:43:59 +03:00
Evgenii Stratonikov
3729865860 compiler: reimplement for-range loops without syscalls
System.Enumerator.Next costs 1_000_000 gas which is rather big for a
single iteration. Reimplement this by saving current counters on stack.
This approach will use 2 PICKITEMS (270_000 gas) for maps, which is
still cheaper that *.Next syscall.
2020-06-22 13:43:58 +03:00
Evgenii Stratonikov
afd8f3b87a compiler: push Null item for nil values 2020-06-17 11:24:11 +03:00
Evgenii Stratonikov
0472a0b0b1 core: move Neo.Runtime/Enumerator/Iterator.* interops to System.* 2020-06-10 12:13:35 +03:00
Anna Shaleva
7a2d37cf7e core: update System.Blockchain.GetBlock interop
closes #1025

Now we put on stack stackitem.Array instead of Interop, so we're able to
use all available block properties without extra interop getters.
Removed Neo.Blockchain.GetBlock interop as we don't need it anymore.
2020-06-09 23:24:04 +03:00
Anna Shaleva
53655c5ac2 core: implement new System.Blockchain.GetTransaction interop
closes #1023

Now we put on stack stackitem.Array instead of Interop, so we don't
need old transaction-related interops anymore. Removed the following
interops:
	System.Transaction.GetHash
	Neo.Transaction.GetAttributes
	Neo.Transaction.GetHash
	Neo.Transaction.GetWitnesses
	Neo.Attribute.GetData
	Neo.Attribute.GetUsage

Also removed the following duplicated NEO interop:
	Neo.Blockchain.GetTransaction
2020-06-09 22:04:13 +03:00
Evgenii Stratonikov
ed45ff98e3 compiler: process interop together with package
Closes #913.
Provide package info in the funcScope to check if function is defined
insided an interop package. As a good side-effect bytecode for builtins from `util`
is no longer emitted.

Related #941.
2020-06-09 12:41:33 +03:00
Anna Shaleva
783f5ecb01 vm: move StackItem to a separate package
closes #912
2020-06-08 13:27:08 +03:00
Evgenii Stratonikov
8cf7871c26 compiler: support nested slice element assignment 2020-05-21 08:30:32 +03:00
Evgenii Stratonikov
5b0e73ddf0 compiler: initialize struct fields explicitly
By default VM initializes every field of a new struct to a Boolean.
If field contains another struct, we need to initialize it to default
value explicitly. This commit sets default values for uninitialized
field.
2020-05-21 08:30:32 +03:00
Evgenii Stratonikov
051e3608ff compiler: support nested struct fielid assignment 2020-05-21 08:30:32 +03:00
Evgenii Stratonikov
1e40f9dac0 compiler: support nested struct reading 2020-05-21 08:30:31 +03:00
Evgenii Stratonikov
1a4a0c154b compiler: support var-declaration of byte slices
Related #801.
2020-05-20 17:45:56 +03:00
Evgenii Stratonikov
3a4ed7dfe8 compiler: emit Buffer for byte slices
All byte slices are mutable so buffer is a right stack item.
2020-05-20 17:45:56 +03:00
Evgenii Stratonikov
b4f1142149 compiler: emit byte constants properly 2020-05-20 17:45:56 +03:00
Evgenii Stratonikov
1b105a9f1d compiler: allow using OP= with struct fields and slice elements
Do it in a generic way, there is no need in restricting to only
variables.
Port of #954.
2020-05-20 14:14:29 +03:00
Evgenii Stratonikov
fdb217ec81 compiler: process _ as a special variable
It is more convenient to drop values inside `emitStoreVar` because this
makes other code has less special cases.
2020-05-20 14:14:29 +03:00
Evgenii Stratonikov
d0735257ce compiler: support range loops with value variables
Closes #958.
2020-05-20 14:14:29 +03:00
Evgenii Stratonikov
b126056f04 compiler: use iterators in range loops
It is simpler than having some counters on stack and will help us to
support maps in future.
2020-05-20 14:14:29 +03:00
Evgenii Stratonikov
34a4c15932 compiler: support byte slice declaration 2020-05-20 11:10:02 +03:00
Evgenii Stratonikov
582469028b compiler: emit default values in a generic way 2020-05-20 11:10:01 +03:00
Evgenii Stratonikov
2cc58c3c9e compiler: allow to declare multiple compound types in a var decl 2020-05-19 16:57:02 +03:00
Evgenii Stratonikov
0629479560 compiler: support non-struct methods
There is no need to restrict ourselves just to structs.
2020-05-19 16:40:26 +03:00
Evgenii Stratonikov
87f6ba34db compiler: process index expresstions in a generic way
All type errors such as string index in slice will be catched during parse phase.
2020-05-19 16:40:26 +03:00
Evgenii Stratonikov
aeaa4a8210 compiler: process bool literals in a generic way 2020-05-19 16:40:26 +03:00
Evgenii Stratonikov
70d0ff869d compiler: refactor typeinfo functions 2020-05-19 16:40:26 +03:00
Evgenii Stratonikov
e21015233b compiler: implement shadowing of global variables
Before introducing slots it was hard to change global variables
preserving changes across multiple function calls.
This commit implements such possibility.
Closes #638.
2020-05-12 16:23:09 +03:00
Evgenii Stratonikov
0cb6dc47e4 vm: implement slot-related opcodes
1. Slot is a new mechanism for storing variables during execution
which is more convenient than alt.stack. This commit implements
support for slot opcodes in both vm and compiler.
2. Remove old alt.stack opcodes.
3. Do not process globals at the start of every function, but instead
load them single time at main.
2020-05-12 16:23:08 +03:00
Evgenii Stratonikov
75fb3af48f compiler: add basic support for function literals
Implement basic support for function literals.
Nested function literals and variables from closure are not supported for now.
2020-05-12 12:56:52 +03:00
Roman Khimov
b83ee77698
Merge pull request #938 from nspcc-dev/fix/appcall
vm: remove APPCALL, TAILCALL
2020-05-08 13:11:02 +03:00
Evgenii Stratonikov
73c82584a3 vm,compiler: replace APPCALL with System.Contract.Call
Contract calls are performed via syscall System.Contract.Call
in NEO3. This implements this in compiler and removes APPCALL from the
VM.
2020-05-07 14:52:03 +03:00
Evgenii Stratonikov
7ac15a7557 compiler: support implicit type in function arguments
Go supports declaring multiple arguments of the same type without
duplicating type name. Now we support this too.
2020-05-07 11:33:09 +03:00
Evgenii Stratonikov
b0a89e8a1a compiler: support named returns 2020-05-06 18:22:52 +03:00
Evgenii Stratonikov
156a2eddc5 compiler: support using return in some branches
When `return` is used in one codepath, but not the other,
we do not clean altstack properly. This commit fixes it.
2020-05-06 18:22:52 +03:00
Evgenii Stratonikov
d18199ce42 vm: implement REVERSE* opcodes
Use new opcodes in the compiler instead of XSWAP/ROLL.
2020-05-06 13:03:49 +03:00
Evgenii Stratonikov
9081211f12 vm: implement NOTEQUAL opcode 2020-04-30 18:00:15 +03:00
Evgenii Stratonikov
519b31a704 vm: remove crypto-related opcodes
All cryptography has moved to interops in NEO3.
There is no SHA256 interop RN, but it is to appear later.
Closes #777.
2020-04-29 19:16:38 +03:00
Evgenii Stratonikov
2fd63387c0 compiler: support CONVERT interops
When result is needed to have certain type, we should have ability
to convert it, with the help of CONVERT opcode.
2020-04-28 16:44:06 +03:00
Evgenii Stratonikov
bfcb1a409f compiler: extend possible returned values
All integer values (int32, uint64...) should be able to be returned.
2020-04-28 16:44:06 +03:00
Evgenii Stratonikov
03761421f8 vm: reorder Array/Map opcodes
Also SIZE can be used for both Arrays/Maps and ByteArrays.
2020-04-24 13:48:44 +03:00
Evgenii Stratonikov
d6624a92ca vm: implement new JMP* and CALL* opcodes
In compiler JMP*_L opcodes are always used, as this requires less effort.
2020-04-24 10:16:41 +03:00
Evgenii Stratonikov
4ad29d0867 compiler: emit Neo.Crypto.ECDsaVerify syscall instead of CHECKSIG
Also change the name of `VerifySignature` interop, to match
syscall's name. It also accepts arguments in different order.
2020-04-13 13:47:39 +03:00
Evgenii Stratonikov
948729137f vm: remove HASH160/HASH256 opcodes 2020-04-13 13:47:39 +03:00
Evgenii Stratonikov
da826522f8 compiler: set variable index on first declaration
This way variables will have indices corresponding to their
order of appearance in a source file.
2020-04-06 15:30:07 +03:00
Evgenii Stratonikov
457e7e006a compiler: support exporting method variables in debug info 2020-04-06 15:30:07 +03:00
Evgenii Stratonikov
5bdee683e6 cli,compiler: support emitting debug info in a file 2020-04-06 15:30:07 +03:00
Evgenii Stratonikov
5d3da26e1e compiler: support sequence points in debug info
Sequence points is a way to map a specific instruction offset
from a compiled contract to a text span in a source file.

This commit implements mapping only for `return` statements.
Further improvements are straight-forward.
2020-04-06 15:30:07 +03:00
Evgenii Stratonikov
24fef35ead compiler: split Compile info sub-functions
Also add tests for basic debug info.
2020-04-06 15:30:07 +03:00
Evgenii Stratonikov
00c40b58aa compiler: record basic debug info
Save info about method's byte-code sections.
2020-04-06 15:30:06 +03:00
Evgenii Stratonikov
efad66aee1 compiler: make Notify accept varargs 2020-04-06 09:31:09 +03:00
Evgenii Stratonikov
3cbd138b67 compiler: allow to declare variables of struct type
Previously, struct variables were initialize with VM's nil value
which is of primitive type. Thus SETITEM used for struct's field
updating wasn't working.
2020-03-27 13:50:09 +03:00
Evgenii Stratonikov
6baed7a010 compiler: allow to declare slices of compound types
Previously this declarations were ignored which resulted
in runtime errors, because VM's nil is an element of primitive type
and can't be converted to an array.
2020-03-27 13:50:09 +03:00
Evgenii Stratonikov
f0b6f783aa compiler: allow for loops with empty condition 2020-03-26 15:00:14 +03:00
Evgenii Stratonikov
2a1402f25d compiler: clean up stack on branch statements
When `return` or `break` statement is encountered inside
a for/range/switch statement, top stack items can be auxilliary.
They need to be cleaned up before returning from the function.
2020-03-10 15:26:00 +03:00
Evgenii Stratonikov
91301df161 compiler: implement fallthrough in switch
Closes #628.
2020-03-10 12:34:07 +03:00
Roman Khimov
e41d434a49 *: move all packages from CityOfZion to nspcc-dev 2020-03-03 17:21:42 +03:00
Evgenii Stratonikov
b461a6ab63 compiler: do not short-circuit in complex conditions
Current implementation of short-circuting is just plain wrong
as it uses `last` or `before-last` labels which meaning depend
on context. It doesn't even handle simple assignements like
`a := x == 1 && y == 2`.

This commit makes all jumps in such conditions local
and adds tests.

Closes #699, #700.
2020-02-28 17:44:46 +03:00
Evgenii Stratonikov
177b725dc1 compiler: make writeJumps return error for bad jumps
The script is invalid anyway so it is better to notify user.
2020-02-21 17:45:45 +03:00