SerpentCompiler:

+ implemented support for:  a = msg(gas, to, value, [1, 2, 3, 4], in_size, out_size)
This commit is contained in:
romanman 2014-06-13 18:17:51 +01:00
parent 211dac858e
commit bbcc1d7eac
4 changed files with 512 additions and 408 deletions

View File

@ -34,7 +34,7 @@ parse: block EOF
parse_init_code_block : 'init' ':' INDENT block DEDENT 'code' ':' INDENT block DEDENT;
block: ( asm | array_assign | assign | contract_storage_assign | special_func | if_elif_else_stmt |
while_stmt | ret_func_1 | ret_func_2 | suicide_func | stop_func | single_send_fund)* ;
while_stmt | ret_func_1 | ret_func_2 | suicide_func | stop_func | single_send_fund | msg_func)* ;
asm: '[asm' asm_symbol 'asm]' NL;
@ -105,7 +105,8 @@ block_difficulty
block_gaslimit
: 'block.gaslimit' ;
msg_func: 'msg' '(' int_val ',' int_val ',' int_val ',' int_val ',' int_val ')' ;
msg_func: 'msg' '(' int_val ',' int_val ',' int_val ',' arr_def ',' int_val ',' int_val')' ;
send_func: 'send' '(' int_val ',' int_val ',' int_val ')';
single_send_fund: send_func NL;
@ -114,7 +115,7 @@ msg_data: 'msg.data' '[' expression ']' ;
array_assign: VAR '[' int_val ']' EQ_OP expression NL;
array_retreive: VAR '[' int_val ']';
assign: VAR EQ_OP (expression | arr_def) NL;
assign: VAR EQ_OP (expression | arr_def | msg_func) NL;
arr_def : '[' (int_val ','?)* ']';
@ -179,7 +180,6 @@ int_val : INT |
special_func |
'(' expression ')' |
OP_NOT '(' expression ')' |
msg_func |
msg_data |
send_func |
contract_storage_load |

View File

@ -1,6 +1,8 @@
package org.ethereum.serpent;
import org.antlr.v4.runtime.misc.NotNull;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.ByteUtil;
import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
@ -199,7 +201,23 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
String varName = ctx.VAR().toString();
int addr = 0;
if (ctx.arr_def() != null){
// msg assigned has two arrays to calc
if (ctx.msg_func() != null){
String msgCode = visitMsg_func(ctx.msg_func());
int outSize = getMsgOutputArraySize(msgCode);
int inSize = getMsgInputArraySize(msgCode);
msgCode = cleanMsgString(msgCode);
String randomArrayName = new String(HashUtil.randomPeerId());
arraysSize.put(randomArrayName, inSize * 32 + 32);
arraysIndex.add(randomArrayName);
arraysSize.put(varName, outSize * 32 + 32);
arraysIndex.add(varName);
return msgCode;
} else if (ctx.arr_def() != null){
// if it's an array the all management is different
String arrayCode = visitArr_def(ctx.arr_def());
@ -211,7 +229,6 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
return arrayCode;
} else{
// if it's an array the all management is different
String expression = visitExpression(ctx.expression());
addr = vars.indexOf(varName);
if (addr == -1){
@ -260,9 +277,6 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
if (ctx.special_func() != null)
return visitSpecial_func(ctx.special_func());
if (ctx.msg_func() != null)
return visitMsg_func(ctx.msg_func());
if (ctx.msg_data() != null)
return visitMsg_data(ctx.msg_data());
@ -292,7 +306,7 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
i += 32;
}
return String.format(" MSIZE %s %d SWAP MSTORE ", arrayInit, arraySize);
return String.format(" MSIZE 32 ADD MSIZE %s %d SWAP MSTORE ", arrayInit, arraySize);
}
@Override
@ -581,14 +595,19 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
@Override
public String visitMsg_func(@NotNull SerpentParser.Msg_funcContext ctx) {
// msg_func: 'msg' '(' int_val ',' int_val ',' int_val ',' arr_def ',' int_val ',' int_val')' ;
// msg_func: 'msg' '(' [gas] ',' [to] ',' [value] ',' arr_def ',' [in_len] ',' [out_len]')' ;
String operand0 = visit(ctx.int_val(0));
String operand1 = visit(ctx.int_val(1));
String operand2 = visit(ctx.int_val(2));
String operand3 = visit(ctx.int_val(3));
String operand4 = visit(ctx.int_val(4));
String operand3 = visit(ctx.arr_def());
String operand4 = visit(ctx.int_val(3));
String operand5 = visit(ctx.int_val(4));
// OUTDATASIZE OUTDATASTART INDATASIZE INDATASTART VALUE TO GAS CALL
return String.format("0 0 %s %s %s %s %s CALL ", operand4, operand3, operand1, operand0, operand2);
return String.format("<out_size %s out_size> <in_size %s in_size> %s %s %s %s %s %s CALL ",
operand5, operand4, operand5, operand4, operand3, operand2, operand1, operand0);
}
@Override
@ -674,6 +693,46 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
}
private Integer getMsgOutputArraySize(String code){
String result = "0";
Pattern pattern = Pattern.compile("<out_size ([0-9])* out_size>");
Matcher matcher = pattern.matcher(code.trim());
if (matcher.find()) {
String group = matcher.group(0);
result = group.replaceAll("<out_size ([0-9]*) out_size>", "$1").trim();
}
return Integer.parseInt(result);
}
private Integer getMsgInputArraySize(String code){
String result = "0";
Pattern pattern = Pattern.compile("<in_size ([0-9])* in_size>");
Matcher matcher = pattern.matcher(code.trim());
if (matcher.find()) {
String group = matcher.group(0);
result = group.replaceAll("<in_size ([0-9]*) in_size>", "$1").trim();
}
return Integer.parseInt(result);
}
private String cleanMsgString (String code){
String result = "";
Pattern pattern = Pattern.compile("<(.*?)>");
result= code.replaceAll("<(.*?)>", "");
return result;
}
private Integer getArraySize(String code){
String result = "0";

View File

@ -1258,7 +1258,7 @@ public class SerpentCompileTest {
String code = "c = 2\n" +
"d = 3\n" +
"a = [11, 22, 33]" ;
String expected = "0 63 MSTORE8 2 0 MSTORE 3 32 MSTORE MSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE";
String expected = "0 63 MSTORE8 2 0 MSTORE 3 32 MSTORE MSIZE DUP DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
@ -1269,12 +1269,24 @@ public class SerpentCompileTest {
public void test46(){
String code = "a = [11, 22, 33]\n" +
"a[ 2 ] = 3" ;
String expected = "MSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 32 2 MUL 32 ADD 0 ADD 0 ADD MSTORE";
String expected = "MSIZE DUP DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 32 2 MUL 32 ADD 0 ADD 0 ADD MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@Test // test arrays 3 simple
public void test46_1(){
String code = "a = [11, 22, 33]\n" ;
String expected = "";
String asmResult = SerpentCompiler.compile(code);
System.out.println(asmResult);
// Assert.assertEquals(expected, asmResult);
}
@Test // test arrays 3 complicated set after 2 arrays
public void test47(){
@ -1282,7 +1294,7 @@ public class SerpentCompileTest {
"b = [12, 14]\n" +
"c = [22, 24, 25]\n" +
"c[ 0 ] = 3" ;
String expected = "MSIZE DUP 32 ADD 2 SWAP MSTORE DUP 64 ADD 4 SWAP MSTORE DUP 96 ADD 6 SWAP MSTORE 128 SWAP MSTORE MSIZE DUP 32 ADD 12 SWAP MSTORE DUP 64 ADD 14 SWAP MSTORE 96 SWAP MSTORE MSIZE DUP 32 ADD 22 SWAP MSTORE DUP 64 ADD 24 SWAP MSTORE DUP 96 ADD 25 SWAP MSTORE 128 SWAP MSTORE 3 32 0 MUL 32 ADD 224 ADD 0 ADD MSTORE";
String expected = "MSIZE DUP DUP 32 ADD 2 SWAP MSTORE DUP 64 ADD 4 SWAP MSTORE DUP 96 ADD 6 SWAP MSTORE 128 SWAP MSTORE MSIZE DUP DUP 32 ADD 12 SWAP MSTORE DUP 64 ADD 14 SWAP MSTORE 96 SWAP MSTORE MSIZE DUP DUP 32 ADD 22 SWAP MSTORE DUP 64 ADD 24 SWAP MSTORE DUP 96 ADD 25 SWAP MSTORE 128 SWAP MSTORE 3 32 0 MUL 32 ADD 224 ADD 0 ADD MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@ -1293,7 +1305,7 @@ public class SerpentCompileTest {
"c = 2\n" +
"a = [11, 22, 33]\n" +
"a[ 2 ] = 3" ;
String expected = "0 63 MSTORE8 1 0 MSTORE 2 32 MSTORE MSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 32 2 MUL 32 ADD 0 ADD 64 ADD MSTORE";
String expected = "0 63 MSTORE8 1 0 MSTORE 2 32 MSTORE MSIZE DUP DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 32 2 MUL 32 ADD 0 ADD 64 ADD MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
@ -1306,12 +1318,25 @@ public class SerpentCompileTest {
String code = "c = [5]\n" +
"a = [11, 22, 33]\n" +
"b = a [0]" ;
String expected = "0 31 MSTORE8 MSIZE DUP 32 ADD 5 SWAP MSTORE 64 SWAP MSTORE MSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 32 0 MUL 96 ADD 32 ADD MLOAD 0 MSTORE";
String expected = "0 31 MSTORE8 MSIZE DUP DUP 32 ADD 5 SWAP MSTORE 64 SWAP MSTORE MSIZE DUP DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 32 0 MUL 96 ADD 32 ADD MLOAD 0 MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
@Test // test msg(gas, to , val, [arr_in], in_len, out_len), and out access
public void test50(){
String code = "\n" +
"a = msg(1, 2, 3, [11, 22, 33], 3, 6) \n" +
"b = a[0]\n" ;
String expected = "0 31 MSTORE8 6 3 MSIZE 32 ADD MSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 3 2 1 CALL 32 0 MUL 160 ADD 32 ADD MLOAD 0 MSTORE";
String asmResult = SerpentCompiler.compile(code);
Assert.assertEquals(expected, asmResult);
}
/*
@ -1334,6 +1359,7 @@ public class SerpentCompileTest {
*/
/**
* todo: a = msg(gas, to , value, in_ptr, in_len, out_ptr, out_len) testing
*
* todo: return(1) testing
* todo: return (1,2) testing
@ -1379,4 +1405,7 @@ public class SerpentCompileTest {
" return(0)" +
*/
// MSTORE DUP DUP MSOTRE8 FUCK I AM LOST FUCK SWAP DUP SWAP DUP DUP
}