Added support for EXIT op (#397)
* EXIT op * changelog * docs * Update CHANGELOG.md
This commit is contained in:
parent
4dd247b159
commit
4bec4e5107
@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
- Added support for `EXIT` opcode via `exit : (string) => 'a` function (behaves same as `ABORT`, but consumes all gas).
|
||||||
- Compiler warnings for the follwing: shadowing, negative spends, division by zero, unused functions, unused includes, unused stateful annotations, unused variables, unused parameters, unused user-defined type, dead return value.
|
- Compiler warnings for the follwing: shadowing, negative spends, division by zero, unused functions, unused includes, unused stateful annotations, unused variables, unused parameters, unused user-defined type, dead return value.
|
||||||
- The pipe operator |>
|
- The pipe operator |>
|
||||||
```
|
```
|
||||||
|
@ -862,6 +862,16 @@ function require(b : bool, err : string) =
|
|||||||
if(!b) abort(err)
|
if(!b) abort(err)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Aside from that, there is an almost equivalent function `exit`
|
||||||
|
|
||||||
|
```sophia
|
||||||
|
exit(reason : string) : 'a
|
||||||
|
```
|
||||||
|
|
||||||
|
Just like `abort`, it breaks the execution with the given reason. The difference
|
||||||
|
however is in the gas consumption — while `abort` returns unused gas, a call to
|
||||||
|
`exit` burns it all.
|
||||||
|
|
||||||
## Delegation signature
|
## Delegation signature
|
||||||
|
|
||||||
Some chain operations (`Oracle.<operation>` and `AENS.<operation>`) have an
|
Some chain operations (`Oracle.<operation>` and `AENS.<operation>`) have an
|
||||||
|
@ -539,8 +539,9 @@ global_env() ->
|
|||||||
%% TTL constructors
|
%% TTL constructors
|
||||||
{"RelativeTTL", Fun1(Int, TTL)},
|
{"RelativeTTL", Fun1(Int, TTL)},
|
||||||
{"FixedTTL", Fun1(Int, TTL)},
|
{"FixedTTL", Fun1(Int, TTL)},
|
||||||
%% Abort
|
%% Abort/exit
|
||||||
{"abort", Fun1(String, A)},
|
{"abort", Fun1(String, A)},
|
||||||
|
{"exit", Fun1(String, A)},
|
||||||
{"require", Fun([Bool, String], Unit)}])
|
{"require", Fun([Bool, String], Unit)}])
|
||||||
, types = MkDefs(
|
, types = MkDefs(
|
||||||
[{"int", 0}, {"bool", 0}, {"char", 0}, {"string", 0}, {"address", 0},
|
[{"int", 0}, {"bool", 0}, {"char", 0}, {"string", 0}, {"address", 0},
|
||||||
|
@ -242,7 +242,7 @@ builtins() ->
|
|||||||
MkName = fun(NS, Fun) ->
|
MkName = fun(NS, Fun) ->
|
||||||
list_to_atom(string:to_lower(string:join(NS ++ [Fun], "_")))
|
list_to_atom(string:to_lower(string:join(NS ++ [Fun], "_")))
|
||||||
end,
|
end,
|
||||||
Scopes = [{[], [{"abort", 1}, {"require", 2}]},
|
Scopes = [{[], [{"abort", 1}, {"require", 2}, {"exit", 1}]},
|
||||||
{["Chain"], [{"spend", 2}, {"balance", 1}, {"block_hash", 1}, {"coinbase", none},
|
{["Chain"], [{"spend", 2}, {"balance", 1}, {"block_hash", 1}, {"coinbase", none},
|
||||||
{"timestamp", none}, {"block_height", none}, {"difficulty", none},
|
{"timestamp", none}, {"block_height", none}, {"difficulty", none},
|
||||||
{"gas_limit", none}, {"bytecode_hash", 1}, {"create", variable}, {"clone", variable}]},
|
{"gas_limit", none}, {"bytecode_hash", 1}, {"create", variable}, {"clone", variable}]},
|
||||||
|
@ -507,6 +507,8 @@ builtin_to_scode(Env, bytes_split, [_, _] = Args) ->
|
|||||||
call_to_scode(Env, aeb_fate_ops:bytes_split(?a, ?a, ?a), Args);
|
call_to_scode(Env, aeb_fate_ops:bytes_split(?a, ?a, ?a), Args);
|
||||||
builtin_to_scode(Env, abort, [_] = Args) ->
|
builtin_to_scode(Env, abort, [_] = Args) ->
|
||||||
call_to_scode(Env, aeb_fate_ops:abort(?a), Args);
|
call_to_scode(Env, aeb_fate_ops:abort(?a), Args);
|
||||||
|
builtin_to_scode(Env, exit, [_] = Args) ->
|
||||||
|
call_to_scode(Env, aeb_fate_ops:exit(?a), Args);
|
||||||
builtin_to_scode(Env, chain_spend, [_, _] = Args) ->
|
builtin_to_scode(Env, chain_spend, [_, _] = Args) ->
|
||||||
call_to_scode(Env, [aeb_fate_ops:spend(?a, ?a),
|
call_to_scode(Env, [aeb_fate_ops:spend(?a, ?a),
|
||||||
tuple(0)], Args);
|
tuple(0)], Args);
|
||||||
@ -1486,6 +1488,7 @@ r_write_to_dead_var({i, Ann, I}, Code) ->
|
|||||||
r_write_to_dead_var(_, _) -> false.
|
r_write_to_dead_var(_, _) -> false.
|
||||||
|
|
||||||
op_view({'ABORT', R}) -> {'ABORT', none, [R]};
|
op_view({'ABORT', R}) -> {'ABORT', none, [R]};
|
||||||
|
op_view({'EXIT', R}) -> {'EXIT', none, [R]};
|
||||||
op_view(T) when is_tuple(T) ->
|
op_view(T) when is_tuple(T) ->
|
||||||
[Op, R | As] = tuple_to_list(T),
|
[Op, R | As] = tuple_to_list(T),
|
||||||
CheckReads = fun(Rs, X) -> case [] == Rs -- [dst, src] of true -> X; false -> false end end,
|
CheckReads = fun(Rs, X) -> case [] == Rs -- [dst, src] of true -> X; false -> false end end,
|
||||||
|
@ -80,3 +80,4 @@ contract AllSyntax =
|
|||||||
let sh : shakespeare(shakespeare(int)) =
|
let sh : shakespeare(shakespeare(int)) =
|
||||||
{wolfgang = state}
|
{wolfgang = state}
|
||||||
sh{wolfgang.wolfgang = sh.wolfgang} // comment
|
sh{wolfgang.wolfgang = sh.wolfgang} // comment
|
||||||
|
exit("hope you had fun reading this")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user