check create_calldata contract without the __call function first
This commit is contained in:
parent
9984679a24
commit
9e908369ec
@ -68,20 +68,13 @@ from_string(ContractBin, Options) when is_binary(ContractBin) ->
|
|||||||
from_string(binary_to_list(ContractBin), Options);
|
from_string(binary_to_list(ContractBin), Options);
|
||||||
from_string(ContractString, Options) ->
|
from_string(ContractString, Options) ->
|
||||||
try
|
try
|
||||||
Ast = parse(ContractString, Options),
|
#{icode := Icode} = string_to_icode(ContractString, Options),
|
||||||
ok = pp_sophia_code(Ast, Options),
|
TypeInfo = extract_type_info(Icode),
|
||||||
ok = pp_ast(Ast, Options),
|
Assembler = assemble(Icode, Options),
|
||||||
TypedAst = aeso_ast_infer_types:infer(Ast, Options),
|
pp_assembler(Assembler, Options),
|
||||||
%% pp_types is handled inside aeso_ast_infer_types.
|
|
||||||
ok = pp_typed_ast(TypedAst, Options),
|
|
||||||
ICode = to_icode(TypedAst, Options),
|
|
||||||
TypeInfo = extract_type_info(ICode),
|
|
||||||
ok = pp_icode(ICode, Options),
|
|
||||||
Assembler = assemble(ICode, Options),
|
|
||||||
ok = pp_assembler(Assembler, Options),
|
|
||||||
ByteCodeList = to_bytecode(Assembler, Options),
|
ByteCodeList = to_bytecode(Assembler, Options),
|
||||||
ByteCode = << << B:8 >> || B <- ByteCodeList >>,
|
ByteCode = << << B:8 >> || B <- ByteCodeList >>,
|
||||||
ok = pp_bytecode(ByteCode, Options),
|
pp_bytecode(ByteCode, Options),
|
||||||
{ok, #{byte_code => ByteCode,
|
{ok, #{byte_code => ByteCode,
|
||||||
compiler_version => version(),
|
compiler_version => version(),
|
||||||
contract_source => ContractString,
|
contract_source => ContractString,
|
||||||
@ -99,6 +92,18 @@ from_string(ContractString, Options) ->
|
|||||||
%% General programming errors in the compiler just signal error.
|
%% General programming errors in the compiler just signal error.
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
string_to_icode(ContractString, Options) ->
|
||||||
|
Ast = parse(ContractString, Options),
|
||||||
|
pp_sophia_code(Ast, Options),
|
||||||
|
pp_ast(Ast, Options),
|
||||||
|
{TypeEnv, TypedAst} = aeso_ast_infer_types:infer(Ast, [return_env | Options]),
|
||||||
|
pp_typed_ast(TypedAst, Options),
|
||||||
|
Icode = ast_to_icode(TypedAst, Options),
|
||||||
|
pp_icode(Icode, Options),
|
||||||
|
#{ typed_ast => TypedAst,
|
||||||
|
type_env => TypeEnv,
|
||||||
|
icode => Icode }.
|
||||||
|
|
||||||
join_errors(Prefix, Errors, Pfun) ->
|
join_errors(Prefix, Errors, Pfun) ->
|
||||||
Ess = [ Pfun(E) || E <- Errors ],
|
Ess = [ Pfun(E) || E <- Errors ],
|
||||||
list_to_binary(string:join([Prefix|Ess], "\n")).
|
list_to_binary(string:join([Prefix|Ess], "\n")).
|
||||||
@ -132,20 +137,17 @@ check_call(Source, FunName, Args, Options) ->
|
|||||||
|
|
||||||
check_call(ContractString0, FunName, Args, Options, PatchFun) ->
|
check_call(ContractString0, FunName, Args, Options, PatchFun) ->
|
||||||
try
|
try
|
||||||
|
%% First check the contract without the __call function and no permissive literals
|
||||||
|
#{} = string_to_icode(ContractString0, Options),
|
||||||
ContractString = insert_call_function(ContractString0, FunName, Args, Options),
|
ContractString = insert_call_function(ContractString0, FunName, Args, Options),
|
||||||
Ast = parse(ContractString, Options),
|
#{typed_ast := TypedAst,
|
||||||
ok = pp_sophia_code(Ast, Options),
|
icode := Icode} = string_to_icode(ContractString, [permissive_address_literals | Options]),
|
||||||
ok = pp_ast(Ast, Options),
|
|
||||||
TypedAst = aeso_ast_infer_types:infer(Ast, [permissive_address_literals]),
|
|
||||||
{ok, {FunName, {fun_t, _, _, ArgTypes, RetType}}} = get_call_type(TypedAst),
|
{ok, {FunName, {fun_t, _, _, ArgTypes, RetType}}} = get_call_type(TypedAst),
|
||||||
ok = pp_typed_ast(TypedAst, Options),
|
|
||||||
Icode = to_icode(TypedAst, Options),
|
|
||||||
ArgVMTypes = [ aeso_ast_to_icode:ast_typerep(T, Icode) || T <- ArgTypes ],
|
ArgVMTypes = [ aeso_ast_to_icode:ast_typerep(T, Icode) || T <- ArgTypes ],
|
||||||
RetVMType = case RetType of
|
RetVMType = case RetType of
|
||||||
{id, _, "_"} -> any;
|
{id, _, "_"} -> any;
|
||||||
_ -> aeso_ast_to_icode:ast_typerep(RetType, Icode)
|
_ -> aeso_ast_to_icode:ast_typerep(RetType, Icode)
|
||||||
end,
|
end,
|
||||||
ok = pp_icode(Icode, Options),
|
|
||||||
#{ functions := Funs } = Icode,
|
#{ functions := Funs } = Icode,
|
||||||
ArgIcode = get_arg_icode(Funs),
|
ArgIcode = get_arg_icode(Funs),
|
||||||
ArgTerms = [ icode_to_term(T, Arg) ||
|
ArgTerms = [ icode_to_term(T, Arg) ||
|
||||||
@ -208,16 +210,12 @@ to_sophia_value(_, _, revert, Data, _Options) ->
|
|||||||
end;
|
end;
|
||||||
to_sophia_value(ContractString, FunName, ok, Data, Options) ->
|
to_sophia_value(ContractString, FunName, ok, Data, Options) ->
|
||||||
try
|
try
|
||||||
Ast = parse(ContractString, Options),
|
#{ typed_ast := TypedAst,
|
||||||
ok = pp_sophia_code(Ast, Options),
|
type_env := TypeEnv,
|
||||||
ok = pp_ast(Ast, Options),
|
icode := Icode } = string_to_icode(ContractString, Options),
|
||||||
{Env, TypedAst} = aeso_ast_infer_types:infer(Ast, [return_env]),
|
|
||||||
ok = pp_typed_ast(TypedAst, Options),
|
|
||||||
{ok, Type0} = get_decode_type(FunName, TypedAst),
|
{ok, Type0} = get_decode_type(FunName, TypedAst),
|
||||||
Type = aeso_ast_infer_types:unfold_types_in_type(Env, Type0, [unfold_record_types, unfold_variant_types]),
|
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
|
||||||
Icode = to_icode(TypedAst, Options),
|
|
||||||
VmType = aeso_ast_to_icode:ast_typerep(Type, Icode),
|
VmType = aeso_ast_to_icode:ast_typerep(Type, Icode),
|
||||||
ok = pp_icode(Icode, Options),
|
|
||||||
case aeso_heap:from_binary(VmType, Data) of
|
case aeso_heap:from_binary(VmType, Data) of
|
||||||
{ok, VmValue} ->
|
{ok, VmValue} ->
|
||||||
try
|
try
|
||||||
@ -374,7 +372,7 @@ icode_to_term(T, V) ->
|
|||||||
icodes_to_terms(Ts, Vs) ->
|
icodes_to_terms(Ts, Vs) ->
|
||||||
[ icode_to_term(T, V) || {T, V} <- lists:zip(Ts, Vs) ].
|
[ icode_to_term(T, V) || {T, V} <- lists:zip(Ts, Vs) ].
|
||||||
|
|
||||||
to_icode(TypedAst, Options) ->
|
ast_to_icode(TypedAst, Options) ->
|
||||||
aeso_ast_to_icode:convert_typed(TypedAst, Options).
|
aeso_ast_to_icode:convert_typed(TypedAst, Options).
|
||||||
|
|
||||||
assemble(Icode, Options) ->
|
assemble(Icode, Options) ->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user