diff --git a/tests/ukm-with-contract/erc_20_token.1.run b/tests/ukm-with-contract/erc_20_token.1.run
index 3aedc1c..a6cc960 100644
--- a/tests/ukm-with-contract/erc_20_token.1.run
+++ b/tests/ukm-with-contract/erc_20_token.1.run
@@ -21,13 +21,11 @@ list_mock SetAccountStorageHook ( 7089066454179379067 , 300 ) ukmNoResult();
list_mock GetAccountStorageHook ( 7089066454178295295 ) ukmIntResult(9700, u256);
list_mock GetAccountStorageHook ( 7089066454179379067 ) ukmIntResult(300, u256);
-push "#init";
-hold_string_from_test_stack;
push "uint256";
hold_list_values_from_test_stack;
push 10000_u256;
hold_list_values_from_test_stack;
-encode_call_data;
+encode_constructor_data;
return_value;
@@ -36,7 +34,8 @@ mock CallData;
push_value 1010101_u160;
mock Caller;
-call_contract 12345;
+init_contract 12345;
+clear_pgm;
return_value;
check_eq ();
diff --git a/ukm-semantics/main/encoding/encoder.md b/ukm-semantics/main/encoding/encoder.md
index a560feb..432662a 100644
--- a/ukm-semantics/main/encoding/encoder.md
+++ b/ukm-semantics/main/encoding/encoder.md
@@ -67,6 +67,8 @@ module UKM-CALLDATA-ENCODER
// then use it here and in the rules below.
rule encodeCallData(FN:String, FAT:List, FAL:List) =>
encodeFunctionSignature(FN, FAT) +Bytes encodeFunctionParams(FAL, FAT, b"")
+ rule encodeConstructorData(FAT:List, FAL:List) =>
+ encodeFunctionParams(FAL, FAT, b"")
// Function signature encoding
rule encodeFunctionSignature(FuncName:String, RL:List) =>
diff --git a/ukm-semantics/main/encoding/syntax.md b/ukm-semantics/main/encoding/syntax.md
index 0f6af3f..469e1eb 100644
--- a/ukm-semantics/main/encoding/syntax.md
+++ b/ukm-semantics/main/encoding/syntax.md
@@ -10,6 +10,7 @@ module UKM-ENCODING-SYNTAX
// TODO: Make these functions total and returning BytesOrError
syntax Bytes ::= encodeCallData (String, List, List) [function] //Function name, argument types, argument list
+ | encodeConstructorData (List, List) [function] // argument types, argument list
| encodeFunctionSignature (String, List) [function]
| encodeFunctionSignatureHelper (List, String) [function]
| encodeFunctionParams (List, List, Bytes) [function]
diff --git a/ukm-semantics/main/execution/dispatch.md b/ukm-semantics/main/execution/dispatch.md
index f7e5743..16dacd9 100644
--- a/ukm-semantics/main/execution/dispatch.md
+++ b/ukm-semantics/main/execution/dispatch.md
@@ -1,7 +1,9 @@
```k
module UKM-EXECUTION-DISPATCH
+ imports private BYTES-SYNTAX
imports private COMMON-K-CELL
+ imports private K-EQUAL-SYNTAX
imports private RUST-REPRESENTATION
imports private RUST-VALUE-SYNTAX
imports private RUST-EXECUTION-CONFIGURATION
@@ -9,12 +11,15 @@ module UKM-EXECUTION-DISPATCH
imports private UKM-EXECUTION-SYNTAX
imports private UKM-PREPROCESSING-CONFIGURATION
- syntax UkmInstruction ::= ukmExecute(contract:Value, gas: ValueOrError)
+ syntax UkmInstruction ::= ukmExecute(create: Bool, contract:Value, gas: ValueOrError)
rule
- ukmExecute(_AccountId:Int, Gas:Int)
- => ukmExecute(struct(ContractTrait, .Map), integerToValue(Gas, u64))
+ // TODO: For some reason, kompile rejects 'Create' as a variabler name below.
+ // Figure out why.
+ ukmExecute(Createy:Bool, Pgm:Bytes, _AccountId:Int, Gas:Int)
+ => ukmExecute(Createy, struct(ContractTrait, .Map), integerToValue(Gas, u64))
+ ~> #if Createy #then Pgm #else .K #fi
...
@@ -22,8 +27,12 @@ module UKM-EXECUTION-DISPATCH
rule
- ukmExecute(... contract: Contract:Value, gas: Gas:Value)
- => ptr(NVI) . dispatcherMethodIdentifier ( ptrValue(null, Gas), .CallParamsList )
+ ukmExecute(... create: Createy:Bool, contract: Contract:Value, gas: Gas:Value)
+ => ptr(NVI) . dispatcherMethodIdentifier
+ ( ptrValue(null, Createy)
+ , ptrValue(null, Gas)
+ , .CallParamsList
+ )
...
Values:Map => Values[NVI <- Contract]
diff --git a/ukm-semantics/main/execution/syntax.md b/ukm-semantics/main/execution/syntax.md
index 52b1158..2ee0238 100644
--- a/ukm-semantics/main/execution/syntax.md
+++ b/ukm-semantics/main/execution/syntax.md
@@ -1,9 +1,11 @@
```k
module UKM-EXECUTION-SYNTAX
+ imports BOOL-SYNTAX
+ imports BYTES-SYNTAX
imports INT-SYNTAX
- syntax UKMInstruction ::= ukmExecute(accountId: Int, gas: Int)
+ syntax UKMInstruction ::= ukmExecute(create: Bool, pgm:Bytes, accountId: Int, gas: Int)
endmodule
diff --git a/ukm-semantics/main/preprocessing/endpoints.md b/ukm-semantics/main/preprocessing/endpoints.md
index 5128220..76bd220 100644
--- a/ukm-semantics/main/preprocessing/endpoints.md
+++ b/ukm-semantics/main/preprocessing/endpoints.md
@@ -117,22 +117,27 @@ module UKM-PREPROCESSING-ENDPOINTS
typePathToPathInExpression(append(TypePath, dispatcherMethodIdentifier))
- self : $selftype , gas : u64, .NormalizedFunctionParameterList
+ self : $selftype , create : bool , gas : u64 , .NormalizedFunctionParameterList
():Type
block({
.InnerAttributes
- concatNonEmptyStatements
- ( let buffer_id = :: ukm :: CallData();
- let ( buffer_id | .PatternNoTopAlts
- , signature | .PatternNoTopAlts
- , .Patterns
- ) = decodeSignature(buffer_id);
- .NonEmptyStatements
- , signatureToCall(signature, keys_list(Signatures), Signatures, buffer_id, gas)
- .NonEmptyStatements
- )
+ let buffer_id = :: ukm :: CallData();
+ if create {
+ .InnerAttributes
+ self . ukmWrap##init ( buffer_id , gas , .CallParamsList );
+ .NonEmptyStatements
+ } else {
+ .InnerAttributes
+ let ( buffer_id | .PatternNoTopAlts
+ , signature | .PatternNoTopAlts
+ , .Patterns
+ ) = decodeSignature(buffer_id);
+ signatureToCall(signature, keys_list(Signatures), Signatures, buffer_id, gas)
+ .NonEmptyStatements
+ };
+ .NonEmptyStatements
})
`emptyOuterAttributes`(.KList)
@@ -142,6 +147,7 @@ module UKM-PREPROCESSING-ENDPOINTS
syntax Identifier ::= "buffer_id" [token]
+ | "create" [token]
| "signature" [token]
| "gas" [token]
| "state_hooks" [token]
@@ -170,6 +176,7 @@ module UKM-PREPROCESSING-ENDPOINTS
| "empty" [token]
| "equals" [token]
| "ukm" [token]
+ | "ukmWrap##init" [token]
| "CallData" [token]
| "EVMC_BAD_JUMP_DESTINATION" [token]
| "EVMC_SUCCESS" [token]
diff --git a/ukm-semantics/targets/execution/configuration.md b/ukm-semantics/targets/execution/configuration.md
index fd6f427..efbae4d 100644
--- a/ukm-semantics/targets/execution/configuration.md
+++ b/ukm-semantics/targets/execution/configuration.md
@@ -13,7 +13,7 @@ module COMMON-K-CELL
configuration
ukmDecodePreprocessedCell($PGM:Bytes)
- ~> ukmExecute($ACCTCODE:Int, $GAS:Int)
+ ~> ukmExecute($CREATE:Bool, $PGM:Bytes, $ACCTCODE:Int, $GAS:Int)
endmodule
diff --git a/ukm-semantics/test/execution.md b/ukm-semantics/test/execution.md
index b0f0d3b..bd03373 100644
--- a/ukm-semantics/test/execution.md
+++ b/ukm-semantics/test/execution.md
@@ -25,7 +25,10 @@ module UKM-TEST-SYNTAX
| "list_mock" UkmHook UkmHookResult
| "encode_call_data"
| "encode_call_data_to_string"
+ | "encode_constructor_data"
| "call_contract" Int
+ | "init_contract" Int
+ | "clear_pgm"
| "hold" KItem
| "output_to_arg"
| "push_status"
@@ -56,7 +59,7 @@ module UKM-TEST-EXECUTION
imports private UKM-HOOKS-UKM-SYNTAX
imports private UKM-REPRESENTATION
imports private UKM-TEST-SYNTAX
- imports RUST-SHARED-SYNTAX
+ imports private RUST-SHARED-SYNTAX
imports private BYTES
syntax Mockable ::= UkmHook
@@ -111,6 +114,17 @@ module UKM-TEST-EXECUTION
...
[owise]
+ rule encode_constructor_data
+ ~> list_values_holder ARGS , list_values_holder PTYPES , .UKMTestTypeHolderList
+ => ukmBytesNew(encodeConstructorData(PTYPES, ARGS))
+ ...
+
+
+ rule encode_constructor_data
+ => ukmBytesNew(encodeConstructorData(.List, .List))
+ ...
+ [owise]
+
rule
mock CallData => mock(CallDataHook(), V) ...
@@ -128,7 +142,11 @@ module UKM-TEST-EXECUTION
rule mock Hook:UkmHook Result:UkmHookResult => mock(Hook, Result)
rule list_mock Hook:UkmHook Result:UkmHookResult => listMock(Hook, Result)
- rule call_contract Account => ukmExecute(Account, 100)
+ rule call_contract Account => ukmExecute(false, .Bytes, Account, 100)
+
+ rule init_contract Account => ukmExecute(true, b"init", Account, 100)
+
+ rule (V:PtrValue ~> b"init" ~> clear_pgm) => V
rule