pass the line number to the parsed instructions for a source map generation #6

This commit is contained in:
Volker Berlin 2019-03-31 11:23:45 +02:00
parent 0b1ff00ae5
commit 5e40f1603e
16 changed files with 334 additions and 259 deletions

View File

@ -244,8 +244,8 @@ class BranchManger {
gotoBlock.op = JavaBlockOperator.LOOP; gotoBlock.op = JavaBlockOperator.LOOP;
gotoBlock.endPosition = conditionEnd; gotoBlock.endPosition = conditionEnd;
instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) ); instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew, gotoBlock.lineNumber ) );
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) ); instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew, gotoBlock.lineNumber ) );
} }
/** /**
@ -743,15 +743,18 @@ class BranchManger {
void handle( CodeInputStream byteCode ) { void handle( CodeInputStream byteCode ) {
int codePosition = -1; int codePosition = -1;
for( int idx = 0; idx < instructions.size(); idx++ ) { for( int idx = 0; idx < instructions.size(); idx++ ) {
int nextCodePosition = instructions.get( idx ).getCodePosition(); WasmInstruction instr = instructions.get( idx );
int lineNumber;
int nextCodePosition = instr.getCodePosition();
if( nextCodePosition <= codePosition ) { if( nextCodePosition <= codePosition ) {
continue; continue;
} else { } else {
codePosition = nextCodePosition; codePosition = nextCodePosition;
lineNumber = instr.getLineNumber();
} }
idx = root.handle( codePosition, instructions, idx ); idx = root.handle( codePosition, instructions, idx, lineNumber );
} }
root.handle( byteCode.getCodePosition(), instructions, instructions.size() ); root.handle( byteCode.getCodePosition(), instructions, instructions.size(), byteCode.getLineNumber() );
} }
/** /**
@ -947,20 +950,22 @@ class BranchManger {
* the target for instructions * the target for instructions
* @param idx * @param idx
* index in the current instruction * index in the current instruction
* @param lineNumber
* the line number in the Java source code
* @return the new index in the instructions * @return the new index in the instructions
*/ */
int handle( int codePosition, List<WasmInstruction> instructions, int idx ) { int handle( int codePosition, List<WasmInstruction> instructions, int idx, int lineNumber ) {
if( codePosition < startPos || codePosition > endPos ) { if( codePosition < startPos || codePosition > endPos ) {
return idx; return idx;
} }
if( codePosition == startPos && startOp != null ) { if( codePosition == startPos && startOp != null ) {
instructions.add( idx++, new WasmBlockInstruction( startOp, data, codePosition ) ); instructions.add( idx++, new WasmBlockInstruction( startOp, data, codePosition, lineNumber ) );
} }
for( BranchNode branch : this ) { for( BranchNode branch : this ) {
idx = branch.handle( codePosition, instructions, idx ); idx = branch.handle( codePosition, instructions, idx, lineNumber );
} }
if( codePosition == endPos && endOp != null ) { if( codePosition == endPos && endOp != null ) {
instructions.add( idx++, new WasmBlockInstruction( endOp, null, codePosition ) ); instructions.add( idx++, new WasmBlockInstruction( endOp, null, codePosition, lineNumber ) );
} }
return idx; return idx;
} }

View File

@ -40,7 +40,7 @@ import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator;
*/ */
class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
private BranchManger branchManager = new BranchManger( getInstructions() ); private BranchManger branchManager = new BranchManger( getInstructions() );
/** /**
* Build the wasm instructions * Build the wasm instructions
@ -67,7 +67,6 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
} }
} }
/** /**
* Write the byte code of a method. * Write the byte code of a method.
* *
@ -80,17 +79,18 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
* @throws WasmException * @throws WasmException
* if some Java code can't converted * if some Java code can't converted
*/ */
private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boolean hasReturn ) throws WasmException { private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boolean hasReturn ) throws WasmException {
try { try {
boolean wide = false; boolean wide = false;
while( byteCode.available() > 0 ) { while( byteCode.available() > 0 ) {
int codePos = byteCode.getCodePosition(); int codePos = byteCode.getCodePosition();
int lineNumber = byteCode.getLineNumber();
int op = byteCode.readUnsignedByte(); int op = byteCode.readUnsignedByte();
switch( op ) { switch( op ) {
case 0: // nop case 0: // nop
break; break;
case 1: // aconst_null case 1: // aconst_null
addStructInstruction( StructOperator.NULL, null, null, codePos ); addStructInstruction( StructOperator.NULL, null, null, codePos, lineNumber );
break; break;
case 2: // iconst_m1 case 2: // iconst_m1
case 3: // iconst_0 case 3: // iconst_0
@ -99,142 +99,142 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
case 6: // iconst_3 case 6: // iconst_3
case 7: // iconst_4 case 7: // iconst_4
case 8: // iconst_5 case 8: // iconst_5
addConstInstruction( Integer.valueOf( op - 3 ), ValueType.i32, codePos ); addConstInstruction( Integer.valueOf( op - 3 ), ValueType.i32, codePos, lineNumber );
break; break;
case 9: // lconst_0 case 9: // lconst_0
case 10: // lconst_1 case 10: // lconst_1
addConstInstruction( Long.valueOf( op - 9 ), ValueType.i64, codePos ); addConstInstruction( Long.valueOf( op - 9 ), ValueType.i64, codePos, lineNumber );
break; break;
case 11: // fconst_0 case 11: // fconst_0
case 12: // fconst_1 case 12: // fconst_1
case 13: // fconst_2 case 13: // fconst_2
addConstInstruction( Float.valueOf( op - 11 ), ValueType.f32, codePos ); addConstInstruction( Float.valueOf( op - 11 ), ValueType.f32, codePos, lineNumber );
break; break;
case 14: // dconst_0 case 14: // dconst_0
case 15: // dconst_1 case 15: // dconst_1
addConstInstruction( Double.valueOf( op - 14 ), ValueType.f64, codePos ); addConstInstruction( Double.valueOf( op - 14 ), ValueType.f64, codePos, lineNumber );
break; break;
case 16: // bipush case 16: // bipush
addConstInstruction( Integer.valueOf( byteCode.readByte() ), ValueType.i32, codePos ); addConstInstruction( Integer.valueOf( byteCode.readByte() ), ValueType.i32, codePos, lineNumber );
break; break;
case 17: // sipush case 17: // sipush
addConstInstruction( Integer.valueOf( byteCode.readShort() ), ValueType.i32, codePos ); addConstInstruction( Integer.valueOf( byteCode.readShort() ), ValueType.i32, codePos, lineNumber );
break; break;
case 18: // ldc case 18: // ldc
addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedByte() ), codePos ); addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedByte() ), codePos, lineNumber );
break; break;
case 19: // ldc_w case 19: // ldc_w
case 20: // ldc2_w case 20: // ldc2_w
addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedShort() ), codePos ); addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedShort() ), codePos, lineNumber );
break; break;
case 21: // iload case 21: // iload
addLoadStoreInstruction( ValueType.i32, true, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.i32, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 22: // lload case 22: // lload
addLoadStoreInstruction( ValueType.i64, true, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.i64, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 23: // fload case 23: // fload
addLoadStoreInstruction( ValueType.f32, true, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.f32, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 24: // dload case 24: // dload
addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 25: // aload case 25: // aload
addLoadStoreInstruction( ValueType.anyref, true, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.anyref, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 26: // iload_0 case 26: // iload_0
case 27: // iload_1 case 27: // iload_1
case 28: // iload_2 case 28: // iload_2
case 29: // iload_3 case 29: // iload_3
addLoadStoreInstruction( ValueType.i32, true, op - 26, codePos ); addLoadStoreInstruction( ValueType.i32, true, op - 26, codePos, lineNumber );
break; break;
case 30: // lload_0 case 30: // lload_0
case 31: // lload_1 case 31: // lload_1
case 32: // lload_2 case 32: // lload_2
case 33: // lload_3 case 33: // lload_3
addLoadStoreInstruction( ValueType.i64, true, op - 30, codePos ); addLoadStoreInstruction( ValueType.i64, true, op - 30, codePos, lineNumber );
break; break;
case 34: // fload_0 case 34: // fload_0
case 35: // fload_1 case 35: // fload_1
case 36: // fload_2 case 36: // fload_2
case 37: // fload_3 case 37: // fload_3
addLoadStoreInstruction( ValueType.f32, true, op - 34, codePos ); addLoadStoreInstruction( ValueType.f32, true, op - 34, codePos, lineNumber );
break; break;
case 38: // dload_0 case 38: // dload_0
case 39: // dload_1 case 39: // dload_1
case 40: // dload_2 case 40: // dload_2
case 41: // dload_3 case 41: // dload_3
addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos ); addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos, lineNumber );
break; break;
case 42: //aload_0 case 42: //aload_0
case 43: //aload_1 case 43: //aload_1
case 44: //aload_2 case 44: //aload_2
case 45: //aload_3 case 45: //aload_3
addLoadStoreInstruction( ValueType.anyref, true, op - 42, codePos ); addLoadStoreInstruction( ValueType.anyref, true, op - 42, codePos, lineNumber );
break; break;
case 46: // iaload case 46: // iaload
addArrayInstruction( ArrayOperator.GET, ValueType.i32, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.i32, codePos, lineNumber );
break; break;
case 47: // laload case 47: // laload
addArrayInstruction( ArrayOperator.GET, ValueType.i64, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.i64, codePos, lineNumber );
break; break;
case 48: // faload case 48: // faload
addArrayInstruction( ArrayOperator.GET, ValueType.f32, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.f32, codePos, lineNumber );
break; break;
case 49: // daload case 49: // daload
addArrayInstruction( ArrayOperator.GET, ValueType.f64, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.f64, codePos, lineNumber );
break; break;
case 50: // aaload case 50: // aaload
AnyType storeType = findPreviousPushInstructionPushValueType(); AnyType storeType = findPreviousPushInstructionPushValueType();
addArrayInstruction( ArrayOperator.GET, storeType, codePos ); addArrayInstruction( ArrayOperator.GET, storeType, codePos, lineNumber );
break; break;
case 51: // baload case 51: // baload
addArrayInstruction( ArrayOperator.GET, ValueType.i8, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.i8, codePos, lineNumber );
break; break;
case 52: // caload case 52: // caload
addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos, lineNumber );
break; break;
case 53: // saload case 53: // saload
addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos ); addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos, lineNumber );
break; break;
case 54: // istore case 54: // istore
addLoadStoreInstruction( ValueType.i32, false, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.i32, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 55: // lstore case 55: // lstore
addLoadStoreInstruction( ValueType.i64, false, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.i64, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 56: // fstore case 56: // fstore
addLoadStoreInstruction( ValueType.f32, false, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.f32, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 57: // dstore case 57: // dstore
addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 58: // astore case 58: // astore
addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedIndex( wide ), codePos ); addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber );
break; break;
case 59: // istore_0 case 59: // istore_0
case 60: // istore_1 case 60: // istore_1
case 61: // istore_2 case 61: // istore_2
case 62: // istore_3 case 62: // istore_3
addLoadStoreInstruction( ValueType.i32, false, op - 59, codePos ); addLoadStoreInstruction( ValueType.i32, false, op - 59, codePos, lineNumber );
break; break;
case 63: // lstore_0 case 63: // lstore_0
case 64: // lstore_1 case 64: // lstore_1
case 65: // lstore_2 case 65: // lstore_2
case 66: // lstore_3 case 66: // lstore_3
addLoadStoreInstruction( ValueType.i64, false, op - 63, codePos ); addLoadStoreInstruction( ValueType.i64, false, op - 63, codePos, lineNumber );
break; break;
case 67: // fstore_0 case 67: // fstore_0
case 68: // fstore_1 case 68: // fstore_1
case 69: // fstore_2 case 69: // fstore_2
case 70: // fstore_3 case 70: // fstore_3
addLoadStoreInstruction( ValueType.f32, false, op - 67, codePos ); addLoadStoreInstruction( ValueType.f32, false, op - 67, codePos, lineNumber );
break; break;
case 71: // dstore_0 case 71: // dstore_0
case 72: // dstore_1 case 72: // dstore_1
case 73: // dstore_2 case 73: // dstore_2
case 74: // dstore_3 case 74: // dstore_3
addLoadStoreInstruction( ValueType.f64, false, op - 71, codePos ); addLoadStoreInstruction( ValueType.f64, false, op - 71, codePos, lineNumber );
break; break;
case 75: // astore_0 case 75: // astore_0
case 76: // astore_1 case 76: // astore_1
@ -245,41 +245,42 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
} else { } else {
storeType = findPreviousPushInstructionPushValueType(); storeType = findPreviousPushInstructionPushValueType();
} }
addLoadStoreInstruction( storeType, false, op - 75, codePos ); addLoadStoreInstruction( storeType, false, op - 75, codePos, lineNumber );
break; break;
case 79: // iastore case 79: // iastore
addArrayInstruction( ArrayOperator.SET, ValueType.i32, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.i32, codePos, lineNumber );
break; break;
case 80: // lastore case 80: // lastore
addArrayInstruction( ArrayOperator.SET, ValueType.i64, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.i64, codePos, lineNumber );
break; break;
case 81: // fastore case 81: // fastore
addArrayInstruction( ArrayOperator.SET, ValueType.f32, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.f32, codePos, lineNumber );
break; break;
case 82: // dastore case 82: // dastore
addArrayInstruction( ArrayOperator.SET, ValueType.f64, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.f64, codePos, lineNumber );
break; break;
case 83: // aastore case 83: // aastore
storeType = findPreviousPushInstructionPushValueType(); storeType = findPreviousPushInstructionPushValueType();
addArrayInstruction( ArrayOperator.SET, storeType, codePos ); addArrayInstruction( ArrayOperator.SET, storeType, codePos, lineNumber );
break; break;
case 84: // bastore case 84: // bastore
addArrayInstruction( ArrayOperator.SET, ValueType.i8, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.i8, codePos, lineNumber );
break; break;
case 85: // castore case 85: // castore
addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos, lineNumber );
break; break;
case 86: // sastore case 86: // sastore
addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos ); addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos, lineNumber );
break; break;
case 87: // pop case 87: // pop
case 88: // pop2 case 88: // pop2
addBlockInstruction( WasmBlockOperator.DROP, null, codePos ); addBlockInstruction( WasmBlockOperator.DROP, null, codePos, lineNumber );
break; break;
case 89: // dup: duplicate the value on top of the stack case 89: // dup: duplicate the value on top of the stack
case 92: // dup2 case 92: // dup2
storeType = findPreviousPushInstructionPushValueType(); storeType = findPreviousPushInstructionPushValueType();
addCallInstruction( new SyntheticFunctionName( "dup" + storeType, "local.get 0 local.get 0 return", storeType, null, storeType, storeType ), codePos ); addCallInstruction( new SyntheticFunctionName( "dup"
+ storeType, "local.get 0 local.get 0 return", storeType, null, storeType, storeType ), codePos, lineNumber );
break; break;
case 90: // dup_x1 case 90: // dup_x1
case 91: // dup_x2 case 91: // dup_x2
@ -287,237 +288,239 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
case 94: // dup2_x2 case 94: // dup2_x2
case 95: // swap case 95: // swap
// can be do with functions with more as one return value in future WASM standard // can be do with functions with more as one return value in future WASM standard
throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: " + op, byteCode.getLineNumber() ); throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: "
+ op, lineNumber );
case 96: // iadd case 96: // iadd
addNumericInstruction( NumericOperator.add, ValueType.i32, codePos); addNumericInstruction( NumericOperator.add, ValueType.i32, codePos, lineNumber );
break; break;
case 97: // ladd case 97: // ladd
addNumericInstruction( NumericOperator.add, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.add, ValueType.i64, codePos, lineNumber );
break; break;
case 98: // fadd case 98: // fadd
addNumericInstruction( NumericOperator.add, ValueType.f32, codePos ); addNumericInstruction( NumericOperator.add, ValueType.f32, codePos, lineNumber );
break; break;
case 99: // dadd case 99: // dadd
addNumericInstruction( NumericOperator.add, ValueType.f64, codePos ); addNumericInstruction( NumericOperator.add, ValueType.f64, codePos, lineNumber );
break; break;
case 100: // isub case 100: // isub
addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber );
break; break;
case 101: // lsub case 101: // lsub
addNumericInstruction( NumericOperator.sub, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.sub, ValueType.i64, codePos, lineNumber );
break; break;
case 102: // fsub case 102: // fsub
addNumericInstruction( NumericOperator.sub, ValueType.f32, codePos ); addNumericInstruction( NumericOperator.sub, ValueType.f32, codePos, lineNumber );
break; break;
case 103: // dsub case 103: // dsub
addNumericInstruction( NumericOperator.sub, ValueType.f64, codePos ); addNumericInstruction( NumericOperator.sub, ValueType.f64, codePos, lineNumber );
break; break;
case 104: // imul; case 104: // imul;
addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos, lineNumber );
break; break;
case 105: // lmul case 105: // lmul
addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos, lineNumber );
break; break;
case 106: // fmul case 106: // fmul
addNumericInstruction( NumericOperator.mul, ValueType.f32, codePos ); addNumericInstruction( NumericOperator.mul, ValueType.f32, codePos, lineNumber );
break; break;
case 107: // dmul case 107: // dmul
addNumericInstruction( NumericOperator.mul, ValueType.f64, codePos ); addNumericInstruction( NumericOperator.mul, ValueType.f64, codePos, lineNumber );
break; break;
case 108: // idiv case 108: // idiv
addNumericInstruction( NumericOperator.div, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.div, ValueType.i32, codePos, lineNumber );
break; break;
case 109: // ldiv case 109: // ldiv
addNumericInstruction( NumericOperator.div, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.div, ValueType.i64, codePos, lineNumber );
break; break;
case 110: // fdiv case 110: // fdiv
addNumericInstruction( NumericOperator.div, ValueType.f32, codePos ); addNumericInstruction( NumericOperator.div, ValueType.f32, codePos, lineNumber );
break; break;
case 111: // ddiv case 111: // ddiv
addNumericInstruction( NumericOperator.div, ValueType.f64, codePos ); addNumericInstruction( NumericOperator.div, ValueType.f64, codePos, lineNumber );
break; break;
case 112: // irem case 112: // irem
addNumericInstruction( NumericOperator.rem, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.rem, ValueType.i32, codePos, lineNumber );
break; break;
case 113: // lrem case 113: // lrem
addNumericInstruction( NumericOperator.rem, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.rem, ValueType.i64, codePos, lineNumber );
break; break;
case 114: // frem case 114: // frem
//helper function like: (a - (int)(a / b) * (float)b) //helper function like: (a - (int)(a / b) * (float)b)
addCallInstruction( new SyntheticFunctionName( "frem", "local.get 0 local.get 0 local.get 1 f32.div i32.trunc_sat_f32_s f32.convert_i32_s local.get 1 f32.mul f32.sub return", ValueType.f32, ValueType.f32, null, ValueType.f32 ), codePos ); addCallInstruction( new SyntheticFunctionName( "frem", "local.get 0 local.get 0 local.get 1 f32.div i32.trunc_sat_f32_s f32.convert_i32_s local.get 1 f32.mul f32.sub return", ValueType.f32, ValueType.f32, null, ValueType.f32 ), codePos, lineNumber );
break; break;
case 115: // drem case 115: // drem
//helper function like: (a - (long)(a / b) * (double)b) //helper function like: (a - (long)(a / b) * (double)b)
addCallInstruction( new SyntheticFunctionName( "drem", "local.get 0 local.get 0 local.get 1 f64.div i64.trunc_sat_f64_s f64.convert_i64_s local.get 1 f64.mul f64.sub return", ValueType.f64, ValueType.f64, null, ValueType.f64 ), codePos ); addCallInstruction( new SyntheticFunctionName( "drem", "local.get 0 local.get 0 local.get 1 f64.div i64.trunc_sat_f64_s f64.convert_i64_s local.get 1 f64.mul f64.sub return", ValueType.f64, ValueType.f64, null, ValueType.f64 ), codePos, lineNumber );
break; break;
case 116: // ineg case 116: // ineg
addConstInstruction( -1, ValueType.i32, codePos ); addConstInstruction( -1, ValueType.i32, codePos, lineNumber );
addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos, lineNumber );
break; break;
case 117: // lneg case 117: // lneg
addConstInstruction( (long)-1, ValueType.i64, codePos ); addConstInstruction( (long)-1, ValueType.i64, codePos, lineNumber );
addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos, lineNumber );
break; break;
case 118: // fneg case 118: // fneg
addNumericInstruction( NumericOperator.neg, ValueType.f32, codePos ); addNumericInstruction( NumericOperator.neg, ValueType.f32, codePos, lineNumber );
break; break;
case 119: // dneg case 119: // dneg
addNumericInstruction( NumericOperator.neg, ValueType.f64, codePos ); addNumericInstruction( NumericOperator.neg, ValueType.f64, codePos, lineNumber );
break; break;
case 120: // ishl case 120: // ishl
addNumericInstruction( NumericOperator.shl, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.shl, ValueType.i32, codePos, lineNumber );
break; break;
case 121: // lshl case 121: // lshl
addConvertInstruction( ValueTypeConvertion.i2l, codePos ); // the shift parameter must be of type long!!! addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); // the shift parameter must be of type long!!!
addNumericInstruction( NumericOperator.shl, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.shl, ValueType.i64, codePos, lineNumber );
break; break;
case 122: // ishr case 122: // ishr
addNumericInstruction( NumericOperator.shr_s, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.shr_s, ValueType.i32, codePos, lineNumber );
break; break;
case 123: // lshr case 123: // lshr
addConvertInstruction( ValueTypeConvertion.i2l, codePos ); // the shift parameter must be of type long!!! addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); // the shift parameter must be of type long!!!
addNumericInstruction( NumericOperator.shr_s, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.shr_s, ValueType.i64, codePos, lineNumber );
break; break;
case 124: // iushr case 124: // iushr
addNumericInstruction( NumericOperator.shr_u, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.shr_u, ValueType.i32, codePos, lineNumber );
break; break;
case 125: // lushr case 125: // lushr
addConvertInstruction( ValueTypeConvertion.i2l, codePos ); // the shift parameter must be of type long!!! addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); // the shift parameter must be of type long!!!
addNumericInstruction( NumericOperator.shr_u, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.shr_u, ValueType.i64, codePos, lineNumber );
break; break;
case 126: // iand case 126: // iand
addNumericInstruction( NumericOperator.and, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.and, ValueType.i32, codePos, lineNumber );
break; break;
case 127: // land case 127: // land
addNumericInstruction( NumericOperator.and, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.and, ValueType.i64, codePos, lineNumber );
break; break;
case 128: // ior case 128: // ior
addNumericInstruction( NumericOperator.or, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.or, ValueType.i32, codePos, lineNumber );
break; break;
case 129: // lor case 129: // lor
addNumericInstruction( NumericOperator.or, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.or, ValueType.i64, codePos, lineNumber );
break; break;
case 130: // ixor case 130: // ixor
addNumericInstruction( NumericOperator.xor, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.xor, ValueType.i32, codePos, lineNumber );
break; break;
case 131: // lxor case 131: // lxor
addNumericInstruction( NumericOperator.xor, ValueType.i64, codePos ); addNumericInstruction( NumericOperator.xor, ValueType.i64, codePos, lineNumber );
break; break;
case 132: // iinc case 132: // iinc
int idx = byteCode.readUnsignedIndex( wide ); int idx = byteCode.readUnsignedIndex( wide );
addLoadStoreInstruction( ValueType.i32, true, idx, codePos ); addLoadStoreInstruction( ValueType.i32, true, idx, codePos, lineNumber );
addConstInstruction( (int)(wide ? byteCode.readShort() : byteCode.readByte()), ValueType.i32, codePos ); addConstInstruction( (int)(wide ? byteCode.readShort() : byteCode.readByte()), ValueType.i32, codePos, lineNumber );
addNumericInstruction( NumericOperator.add, ValueType.i32, codePos); addNumericInstruction( NumericOperator.add, ValueType.i32, codePos, lineNumber );
addLoadStoreInstruction( ValueType.i32, false, idx, codePos ); addLoadStoreInstruction( ValueType.i32, false, idx, codePos, lineNumber );
break; break;
case 133: // i2l case 133: // i2l
addConvertInstruction( ValueTypeConvertion.i2l, codePos ); addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber );
break; break;
case 134: // i2f case 134: // i2f
addConvertInstruction( ValueTypeConvertion.i2f, codePos ); addConvertInstruction( ValueTypeConvertion.i2f, codePos, lineNumber );
break; break;
case 135: // i2d case 135: // i2d
addConvertInstruction( ValueTypeConvertion.i2d, codePos ); addConvertInstruction( ValueTypeConvertion.i2d, codePos, lineNumber );
break; break;
case 136: // l2i case 136: // l2i
addConvertInstruction( ValueTypeConvertion.l2i, codePos ); addConvertInstruction( ValueTypeConvertion.l2i, codePos, lineNumber );
break; break;
case 137: // l2f case 137: // l2f
addConvertInstruction( ValueTypeConvertion.l2f, codePos ); addConvertInstruction( ValueTypeConvertion.l2f, codePos, lineNumber );
break; break;
case 138: // l2d case 138: // l2d
addConvertInstruction( ValueTypeConvertion.l2d, codePos ); addConvertInstruction( ValueTypeConvertion.l2d, codePos, lineNumber );
break; break;
case 139: // f2i case 139: // f2i
addConvertInstruction( ValueTypeConvertion.f2i, codePos ); addConvertInstruction( ValueTypeConvertion.f2i, codePos, lineNumber );
break; break;
case 140: // f2l case 140: // f2l
addConvertInstruction( ValueTypeConvertion.f2l, codePos ); addConvertInstruction( ValueTypeConvertion.f2l, codePos, lineNumber );
break; break;
case 141: // f2d case 141: // f2d
addConvertInstruction( ValueTypeConvertion.f2d, codePos ); addConvertInstruction( ValueTypeConvertion.f2d, codePos, lineNumber );
break; break;
case 142: // d2i case 142: // d2i
addConvertInstruction( ValueTypeConvertion.d2i, codePos ); addConvertInstruction( ValueTypeConvertion.d2i, codePos, lineNumber );
break; break;
case 143: // d2l case 143: // d2l
addConvertInstruction( ValueTypeConvertion.d2l, codePos ); addConvertInstruction( ValueTypeConvertion.d2l, codePos, lineNumber );
break; break;
case 144: // d2f case 144: // d2f
addConvertInstruction( ValueTypeConvertion.d2f, codePos ); addConvertInstruction( ValueTypeConvertion.d2f, codePos, lineNumber );
break; break;
case 145: // i2b case 145: // i2b
addConvertInstruction( ValueTypeConvertion.i2b, codePos ); addConvertInstruction( ValueTypeConvertion.i2b, codePos, lineNumber );
break; break;
case 146: // i2c case 146: // i2c
addConstInstruction( 0xFFFF, ValueType.i32, codePos ); addConstInstruction( 0xFFFF, ValueType.i32, codePos, lineNumber );
addNumericInstruction( NumericOperator.and, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.and, ValueType.i32, codePos, lineNumber );
break; break;
case 147: // i2s case 147: // i2s
addConvertInstruction( ValueTypeConvertion.i2s, codePos ); addConvertInstruction( ValueTypeConvertion.i2s, codePos, lineNumber );
break; break;
case 148: // lcmp case 148: // lcmp
opCompare( ValueType.i64, byteCode, codePos ); opCompare( ValueType.i64, byteCode, codePos, lineNumber );
break; break;
case 149: // fcmpl case 149: // fcmpl
case 150: // fcmpg case 150: // fcmpg
opCompare( ValueType.f32, byteCode, codePos ); opCompare( ValueType.f32, byteCode, codePos, lineNumber );
break; break;
case 151: // dcmpl case 151: // dcmpl
case 152: // dcmpg case 152: // dcmpg
opCompare( ValueType.f64, byteCode, codePos ); opCompare( ValueType.f64, byteCode, codePos, lineNumber );
break; break;
case 153: // ifeq case 153: // ifeq
opIfCondition( NumericOperator.eq, byteCode, codePos ); opIfCondition( NumericOperator.eq, byteCode, codePos, lineNumber );
break; break;
case 154: // ifne case 154: // ifne
opIfCondition( NumericOperator.ne, byteCode, codePos ); opIfCondition( NumericOperator.ne, byteCode, codePos, lineNumber );
break; break;
case 155: // iflt case 155: // iflt
opIfCondition( NumericOperator.lt, byteCode, codePos ); opIfCondition( NumericOperator.lt, byteCode, codePos, lineNumber );
break; break;
case 156: // ifge case 156: // ifge
opIfCondition( NumericOperator.ge, byteCode, codePos ); opIfCondition( NumericOperator.ge, byteCode, codePos, lineNumber );
break; break;
case 157: // ifgt case 157: // ifgt
opIfCondition( NumericOperator.gt, byteCode, codePos ); opIfCondition( NumericOperator.gt, byteCode, codePos, lineNumber );
break; break;
case 158: // ifle case 158: // ifle
opIfCondition( NumericOperator.le, byteCode, codePos ); opIfCondition( NumericOperator.le, byteCode, codePos, lineNumber );
break; break;
case 159: // if_icmpeq case 159: // if_icmpeq
opIfCompareCondition( NumericOperator.eq, byteCode, codePos ); opIfCompareCondition( NumericOperator.eq, byteCode, codePos, lineNumber );
break; break;
case 160: // if_icmpne case 160: // if_icmpne
opIfCompareCondition( NumericOperator.ne, byteCode, codePos ); opIfCompareCondition( NumericOperator.ne, byteCode, codePos, lineNumber );
break; break;
case 161: // if_icmplt case 161: // if_icmplt
opIfCompareCondition( NumericOperator.lt, byteCode, codePos ); opIfCompareCondition( NumericOperator.lt, byteCode, codePos, lineNumber );
break; break;
case 162: // if_icmpge case 162: // if_icmpge
opIfCompareCondition( NumericOperator.ge, byteCode, codePos ); opIfCompareCondition( NumericOperator.ge, byteCode, codePos, lineNumber );
break; break;
case 163: // if_icmpgt case 163: // if_icmpgt
opIfCompareCondition( NumericOperator.gt, byteCode, codePos ); opIfCompareCondition( NumericOperator.gt, byteCode, codePos, lineNumber );
break; break;
case 164: // if_icmple case 164: // if_icmple
opIfCompareCondition( NumericOperator.le, byteCode, codePos ); opIfCompareCondition( NumericOperator.le, byteCode, codePos, lineNumber );
break; break;
case 165: // if_acmpeq case 165: // if_acmpeq
opIfCompareCondition( NumericOperator.ref_eq, byteCode, codePos ); opIfCompareCondition( NumericOperator.ref_eq, byteCode, codePos, lineNumber );
break; break;
case 166: // if_acmpne case 166: // if_acmpne
opIfCompareCondition( NumericOperator.ref_ne, byteCode, codePos ); opIfCompareCondition( NumericOperator.ref_ne, byteCode, codePos, lineNumber );
break; break;
case 167: // goto case 167: // goto
int offset = byteCode.readShort(); int offset = byteCode.readShort();
branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), byteCode.getLineNumber() ); branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), lineNumber );
addNopInstruction( codePos ); // marker of the line number for the branch manager addNopInstruction( codePos, lineNumber ); // marker of the line number for the branch manager
break; break;
case 168: // jsr case 168: // jsr
case 169: // ret case 169: // ret
case 201: // jsr_w case 201: // jsr_w
throw new WasmException( "Finally block of Java 5 or older is not supported. Compile the sources with a Java SE 6 or newer: " + op, byteCode.getLineNumber() ); throw new WasmException( "Finally block of Java 5 or older is not supported. Compile the sources with a Java SE 6 or newer: "
+ op, lineNumber );
case 170: // tableswitch case 170: // tableswitch
case 171: // lookupswitch case 171: // lookupswitch
writeSwitchCode( byteCode, op == 171 ); writeSwitchCode( byteCode, op == 171 );
@ -529,7 +532,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
case 176: // areturn case 176: // areturn
case 177: // return void case 177: // return void
ValueType type = null; ValueType type = null;
switch ( op ) { switch( op ) {
case 172: // ireturn case 172: // ireturn
type = ValueType.i32; type = ValueType.i32;
break; break;
@ -546,43 +549,43 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
type = ValueType.anyref; type = ValueType.anyref;
break; break;
} }
addBlockInstruction( WasmBlockOperator.RETURN, type, codePos ); addBlockInstruction( WasmBlockOperator.RETURN, type, codePos, lineNumber );
break; break;
case 178: // getstatic case 178: // getstatic
ConstantRef ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); ConstantRef ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
addGlobalInstruction( true, ref, codePos ); addGlobalInstruction( true, ref, codePos, lineNumber );
break; break;
case 179: // putstatic case 179: // putstatic
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
addGlobalInstruction( false, ref, codePos ); addGlobalInstruction( false, ref, codePos, lineNumber );
break; break;
case 180: // getfield case 180: // getfield
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
addStructInstruction( StructOperator.GET, ref.getClassName(), ref.getName(), codePos ); addStructInstruction( StructOperator.GET, ref.getClassName(), ref.getName(), codePos, lineNumber );
break; break;
case 181: // putfield case 181: // putfield
ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
addStructInstruction( StructOperator.SET, ref.getClassName(), ref.getName(), codePos ); addStructInstruction( StructOperator.SET, ref.getClassName(), ref.getName(), codePos, lineNumber );
break; break;
case 182: // invokevirtual case 182: // invokevirtual
case 183: // invokespecial, invoke a constructor case 183: // invokespecial, invoke a constructor
case 184: // invokestatic case 184: // invokestatic
idx = byteCode.readUnsignedShort(); idx = byteCode.readUnsignedShort();
ref = (ConstantRef)constantPool.get( idx ); ref = (ConstantRef)constantPool.get( idx );
addCallInstruction( new FunctionName( ref ), codePos ); addCallInstruction( new FunctionName( ref ), codePos, lineNumber );
break; break;
//TODO case 185: // invokeinterface //TODO case 185: // invokeinterface
//TODO case 186: // invokedynamic //TODO case 186: // invokedynamic
case 187: // new case 187: // new
String name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName(); String name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName();
addStructInstruction( StructOperator.NEW_DEFAULT, name, null, codePos ); addStructInstruction( StructOperator.NEW_DEFAULT, name, null, codePos, lineNumber );
break; break;
case 188: // newarray case 188: // newarray
int typeValue = byteCode.readByte(); int typeValue = byteCode.readByte();
switch( typeValue ) { switch( typeValue ) {
case 4: // boolean case 4: // boolean
case 5: // char case 5: // char
type = ValueType.i32; type = ValueType.i32;
break; break;
case 6: //float case 6: //float
type = ValueType.f32; type = ValueType.f32;
@ -599,28 +602,28 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
type = ValueType.i64; type = ValueType.i64;
break; break;
default: default:
throw new WasmException( "Invalid Java byte code newarray: " + typeValue, byteCode.getLineNumber() ); throw new WasmException( "Invalid Java byte code newarray: " + typeValue, lineNumber );
} }
addArrayInstruction( ArrayOperator.NEW, type, codePos ); addArrayInstruction( ArrayOperator.NEW, type, codePos, lineNumber );
break; break;
case 189: // anewarray case 189: // anewarray
name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName(); name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName();
type = ValueType.anyref; //TODO we need to use the right type from name type = ValueType.anyref; //TODO we need to use the right type from name
addArrayInstruction( ArrayOperator.NEW, type, codePos ); addArrayInstruction( ArrayOperator.NEW, type, codePos, lineNumber );
break; break;
case 190: // arraylength case 190: // arraylength
addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos ); addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos, lineNumber );
break; break;
case 191: // athrow case 191: // athrow
addBlockInstruction( WasmBlockOperator.THROW, null, codePos ); addBlockInstruction( WasmBlockOperator.THROW, null, codePos, lineNumber );
break; break;
//TODO case 192: // checkcast //TODO case 192: // checkcast
//TODO case 193: // instanceof //TODO case 193: // instanceof
case 194: // monitorenter case 194: // monitorenter
addBlockInstruction( WasmBlockOperator.MONITOR_ENTER, null, codePos ); addBlockInstruction( WasmBlockOperator.MONITOR_ENTER, null, codePos, lineNumber );
break; break;
case 195: // monitorexit case 195: // monitorexit
addBlockInstruction( WasmBlockOperator.MONITOR_EXIT, null, codePos ); addBlockInstruction( WasmBlockOperator.MONITOR_EXIT, null, codePos, lineNumber );
break; break;
case 196: // wide case 196: // wide
// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide // https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide
@ -628,18 +631,18 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
continue; continue;
//TODO case 197: // multianewarray //TODO case 197: // multianewarray
case 198: // ifnull case 198: // ifnull
opIfCompareCondition( NumericOperator.ifnull, byteCode, codePos ); opIfCompareCondition( NumericOperator.ifnull, byteCode, codePos, lineNumber );
break; break;
case 199: // ifnonnull case 199: // ifnonnull
opIfCompareCondition( NumericOperator.ifnonnull, byteCode, codePos ); opIfCompareCondition( NumericOperator.ifnonnull, byteCode, codePos, lineNumber );
break; break;
case 200: // goto_w case 200: // goto_w
offset = byteCode.readInt(); offset = byteCode.readInt();
branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), byteCode.getLineNumber() ); branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), lineNumber );
addNopInstruction( codePos ); // marker of the line number for the branch manager addNopInstruction( codePos, lineNumber ); // marker of the line number for the branch manager
break; break;
default: default:
throw new WasmException( "Unimplemented Java byte code operation: " + op, byteCode.getLineNumber() ); throw new WasmException( "Unimplemented Java byte code operation: " + op, lineNumber );
} }
wide = false; wide = false;
} }
@ -649,7 +652,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
// if a method ends with a loop or block without a break then code after the loop is no reachable // if a method ends with a loop or block without a break then code after the loop is no reachable
// Java does not need a return byte code in this case // Java does not need a return byte code in this case
// But WebAssembly need the dead code to validate // But WebAssembly need the dead code to validate
addBlockInstruction( WasmBlockOperator.UNREACHABLE, null, byteCode.getCodePosition() ); addBlockInstruction( WasmBlockOperator.UNREACHABLE, null, byteCode.getCodePosition(), byteCode.getLineNumber() );
} }
} catch( WasmException ex ) { } catch( WasmException ex ) {
throw ex; throw ex;
@ -694,7 +697,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
int block = 0; int block = 0;
int defaultBlock = -1; int defaultBlock = -1;
int currentPos = -1; int currentPos = -1;
addLoadStoreInstruction( ValueType.i32, false, tempI32, codePos ); addLoadStoreInstruction( ValueType.i32, false, tempI32, codePos, lineNumber );
do { do {
int nextPos = findNext( currentPos, positions ); int nextPos = findNext( currentPos, positions );
if( nextPos == currentPos ) { if( nextPos == currentPos ) {
@ -711,10 +714,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
} }
for( int i = 0; i < positions.length; i++ ) { for( int i = 0; i < positions.length; i++ ) {
if( positions[i] == currentPos ) { if( positions[i] == currentPos ) {
addLoadStoreInstruction( ValueType.i32, true, tempI32, codePos ); addLoadStoreInstruction( ValueType.i32, true, tempI32, codePos, lineNumber );
addConstInstruction( keys[i], ValueType.i32, codePos ); addConstInstruction( keys[i], ValueType.i32, codePos, lineNumber );
addNumericInstruction( NumericOperator.eq, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.eq, ValueType.i32, codePos, lineNumber );
addBlockInstruction( WasmBlockOperator.BR_IF, block, codePos ); addBlockInstruction( WasmBlockOperator.BR_IF, block, codePos, lineNumber );
} }
} }
block++; block++;
@ -722,7 +725,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
if( defaultBlock < 0 ) { if( defaultBlock < 0 ) {
defaultBlock = block; defaultBlock = block;
} }
addBlockInstruction( WasmBlockOperator.BR, defaultBlock, codePos ); addBlockInstruction( WasmBlockOperator.BR, defaultBlock, codePos, lineNumber );
} else { } else {
int low = byteCode.readInt(); int low = byteCode.readInt();
keys = null; keys = null;
@ -732,8 +735,8 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
positions[i] = startPosition + byteCode.readInt(); positions[i] = startPosition + byteCode.readInt();
} }
if( low != 0 ) { // the br_table starts ever with the value 0. That we need to subtract the start value if it different if( low != 0 ) { // the br_table starts ever with the value 0. That we need to subtract the start value if it different
addConstInstruction( low, ValueType.i32, codePos ); addConstInstruction( low, ValueType.i32, codePos, lineNumber );
addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos ); addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber );
} }
} }
branchManager.addSwitchOperator( switchValuestartPosition, 0, lineNumber, keys, positions, defaultPosition ); branchManager.addSwitchOperator( switchValuestartPosition, 0, lineNumber, keys, positions, defaultPosition );
@ -810,38 +813,42 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
* Handle the if<condition> of the Java byte code. This Java instruction compare the first stack value with value 0. * Handle the if<condition> of the Java byte code. This Java instruction compare the first stack value with value 0.
* Important: In the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we * Important: In the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we
* need to use condition for the if block. The caller of the method must already negate this * need to use condition for the if block. The caller of the method must already negate this
*
* @param compareOp * @param compareOp
* The condition for the continue of a loop. * The condition for the continue of a loop.
* @param byteCode * @param byteCode
* current byte code stream to read the target offset. * current byte code stream to read the target offset.
* @param codePos * @param codePos
* the code position/offset in the Java method * the code position/offset in the Java method
* * @param lineNumber
* the line number in the Java source code
* @throws IOException * @throws IOException
* if any I/O errors occur. * if any I/O errors occur.
*/ */
private void opIfCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos ) throws IOException { private void opIfCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos, int lineNumber ) throws IOException {
addConstInstruction( 0, ValueType.i32, codePos ); addConstInstruction( 0, ValueType.i32, codePos, lineNumber );
opIfCompareCondition( compareOp, byteCode, codePos ); opIfCompareCondition( compareOp, byteCode, codePos, lineNumber );
} }
/** /**
* Handle the if<condition> of the Java byte code. This Java instruction compare 2 values from stack. * Handle the if<condition> of the Java byte code. This Java instruction compare 2 values from stack. Important: In
* Important: In the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we need to use * the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we need to use
* condition for the if block. The caller of the method must already negate this. * condition for the if block. The caller of the method must already negate this.
*
* @param compareOp * @param compareOp
* The condition for the continue of a loop. * The condition for the continue of a loop.
* @param byteCode * @param byteCode
* current byte code stream to read the target offset. * current byte code stream to read the target offset.
* @param codePos * @param codePos
* the code position/offset in the Java method * the code position/offset in the Java method
* * @param lineNumber
* the line number in the Java source code
* @throws IOException * @throws IOException
* if any I/O errors occur. * if any I/O errors occur.
*/ */
private void opIfCompareCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos ) throws IOException { private void opIfCompareCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos, int lineNumber ) throws IOException {
int offset = byteCode.readShort(); int offset = byteCode.readShort();
WasmNumericInstruction compare = new WasmNumericInstruction( compareOp, ValueType.i32, codePos ); WasmNumericInstruction compare = new WasmNumericInstruction( compareOp, ValueType.i32, codePos, lineNumber );
branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare ); branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare );
getInstructions().add( compare ); getInstructions().add( compare );
} }
@ -856,14 +863,16 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
* current byte code stream to read the next operation. * current byte code stream to read the next operation.
* @param codePos * @param codePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
* @throws IOException * @throws IOException
* if any I/O errors occur. * if any I/O errors occur.
*/ */
private void opCompare( ValueType valueType, CodeInputStream byteCode, int codePos ) throws IOException { private void opCompare( ValueType valueType, CodeInputStream byteCode, int codePos, int lineNumber ) throws IOException {
codePos = byteCode.getCodePosition(); codePos = byteCode.getCodePosition();
NumericOperator numOp; NumericOperator numOp;
int nextOp = byteCode.read(); int nextOp = byteCode.read();
switch( nextOp ){ switch( nextOp ) {
case 153: // ifeq case 153: // ifeq
numOp = NumericOperator.eq; numOp = NumericOperator.eq;
break; break;
@ -886,7 +895,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
throw new WasmException( "Unexpected compare sub operation: " + nextOp, -1 ); throw new WasmException( "Unexpected compare sub operation: " + nextOp, -1 );
} }
int offset = byteCode.readShort(); int offset = byteCode.readShort();
WasmNumericInstruction compare = new WasmNumericInstruction( numOp, valueType, codePos ); WasmNumericInstruction compare = new WasmNumericInstruction( numOp, valueType, codePos, lineNumber );
branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare ); branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare );
getInstructions().add( compare ); getInstructions().add( compare );
} }

View File

@ -47,9 +47,11 @@ class WasmArrayInstruction extends WasmInstruction {
* the type of the parameters * the type of the parameters
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmArrayInstruction( @Nullable ArrayOperator op, @Nullable AnyType type, int javaCodePos ) { WasmArrayInstruction( @Nullable ArrayOperator op, @Nullable AnyType type, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.op = op; this.op = op;
this.type = type; this.type = type;
} }

View File

@ -46,9 +46,11 @@ class WasmBlockInstruction extends WasmInstruction {
* extra data depending of the operator * extra data depending of the operator
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmBlockInstruction( @Nonnull WasmBlockOperator op, @Nullable Object data, int javaCodePos ) { WasmBlockInstruction( @Nonnull WasmBlockOperator op, @Nullable Object data, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.op = op; this.op = op;
this.data = data; this.data = data;
} }

View File

@ -44,9 +44,11 @@ class WasmCallInstruction extends WasmInstruction {
* the function name that should be called * the function name that should be called
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmCallInstruction( FunctionName name, int javaCodePos ) { WasmCallInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.name = name; this.name = name;
} }

View File

@ -113,11 +113,13 @@ public abstract class WasmCodeBuilder {
* the memory/slot index of the variable in Java byte code * the memory/slot index of the variable in Java byte code
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
@Nonnull @Nonnull
protected void addLoadStoreInstruction( AnyType valueType, boolean load, @Nonnegative int javaIdx, int javaCodePos ) { protected void addLoadStoreInstruction( AnyType valueType, boolean load, @Nonnegative int javaIdx, int javaCodePos, int lineNumber ) {
localVariables.use( valueType, javaIdx ); localVariables.use( valueType, javaIdx );
instructions.add( new WasmLoadStoreInstruction( load, javaIdx, localVariables, javaCodePos ) ); instructions.add( new WasmLoadStoreInstruction( load, javaIdx, localVariables, javaCodePos, lineNumber ) );
} }
/** /**
@ -129,10 +131,12 @@ public abstract class WasmCodeBuilder {
* the index of the variable * the index of the variable
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
@Nonnull @Nonnull
protected void addLocalInstruction( boolean load, @Nonnegative int wasmIdx, int javaCodePos ) { protected void addLocalInstruction( boolean load, @Nonnegative int wasmIdx, int javaCodePos, int lineNumber ) {
instructions.add( new WasmLocalInstruction( load, wasmIdx, javaCodePos ) ); instructions.add( new WasmLocalInstruction( load, wasmIdx, javaCodePos, lineNumber ) );
} }
/** /**
@ -144,9 +148,11 @@ public abstract class WasmCodeBuilder {
* reference to a static field * reference to a static field
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addGlobalInstruction( boolean load, Member ref, int javaCodePos ) { protected void addGlobalInstruction( boolean load, Member ref, int javaCodePos, int lineNumber ) {
instructions.add( new WasmGlobalInstruction( load, ref, javaCodePos ) ); instructions.add( new WasmGlobalInstruction( load, ref, javaCodePos, lineNumber ) );
} }
/** /**
@ -158,9 +164,11 @@ public abstract class WasmCodeBuilder {
* the value type * the value type
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addConstInstruction( Number value, ValueType valueType, int javaCodePos ) { protected void addConstInstruction( Number value, ValueType valueType, int javaCodePos, int lineNumber ) {
instructions.add( new WasmConstInstruction( value, valueType, javaCodePos ) ); instructions.add( new WasmConstInstruction( value, valueType, javaCodePos, lineNumber ) );
} }
/** /**
@ -170,9 +178,11 @@ public abstract class WasmCodeBuilder {
* the value * the value
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addConstInstruction( Number value, int javaCodePos ) { protected void addConstInstruction( Number value, int javaCodePos, int lineNumber ) {
instructions.add( new WasmConstInstruction( value, javaCodePos ) ); instructions.add( new WasmConstInstruction( value, javaCodePos, lineNumber ) );
} }
/** /**
@ -184,9 +194,11 @@ public abstract class WasmCodeBuilder {
* the value type * the value type
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addNumericInstruction( @Nullable NumericOperator numOp, @Nullable ValueType valueType, int javaCodePos ) { protected void addNumericInstruction( @Nullable NumericOperator numOp, @Nullable ValueType valueType, int javaCodePos, int lineNumber ) {
instructions.add( new WasmNumericInstruction( numOp, valueType, javaCodePos ) ); instructions.add( new WasmNumericInstruction( numOp, valueType, javaCodePos, lineNumber ) );
} }
/** /**
@ -196,9 +208,11 @@ public abstract class WasmCodeBuilder {
* the conversion * the conversion
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addConvertInstruction( ValueTypeConvertion conversion, int javaCodePos ) { protected void addConvertInstruction( ValueTypeConvertion conversion, int javaCodePos, int lineNumber ) {
instructions.add( new WasmConvertInstruction( conversion, javaCodePos ) ); instructions.add( new WasmConvertInstruction( conversion, javaCodePos, lineNumber ) );
} }
/** /**
@ -208,9 +222,11 @@ public abstract class WasmCodeBuilder {
* the function name that should be called * the function name that should be called
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addCallInstruction( FunctionName name, int javaCodePos ) { protected void addCallInstruction( FunctionName name, int javaCodePos, int lineNumber ) {
instructions.add( new WasmCallInstruction( name, javaCodePos ) ); instructions.add( new WasmCallInstruction( name, javaCodePos, lineNumber ) );
} }
/** /**
@ -222,9 +238,11 @@ public abstract class WasmCodeBuilder {
* extra data for some operations * extra data for some operations
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addBlockInstruction( WasmBlockOperator op, @Nullable Object data, int javaCodePos ) { protected void addBlockInstruction( WasmBlockOperator op, @Nullable Object data, int javaCodePos, int lineNumber ) {
instructions.add( new WasmBlockInstruction( op, data, javaCodePos ) ); instructions.add( new WasmBlockInstruction( op, data, javaCodePos, lineNumber ) );
} }
/** /**
@ -233,9 +251,11 @@ public abstract class WasmCodeBuilder {
* *
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addNopInstruction( int javaCodePos ) { protected void addNopInstruction( int javaCodePos, int lineNumber ) {
instructions.add( new WasmNopInstruction( javaCodePos ) ); instructions.add( new WasmNopInstruction( javaCodePos, lineNumber ) );
} }
/** /**
@ -247,9 +267,11 @@ public abstract class WasmCodeBuilder {
* the array type * the array type
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addArrayInstruction( ArrayOperator op, AnyType type, int javaCodePos ) { protected void addArrayInstruction( ArrayOperator op, AnyType type, int javaCodePos, int lineNumber ) {
instructions.add( new WasmArrayInstruction( op, type, javaCodePos ) ); instructions.add( new WasmArrayInstruction( op, type, javaCodePos, lineNumber ) );
} }
/** /**
@ -263,8 +285,10 @@ public abstract class WasmCodeBuilder {
* the name of field if needed for the operation * the name of field if needed for the operation
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
protected void addStructInstruction( StructOperator op, @Nullable String typeName, @Nullable String fieldName, int javaCodePos ) { protected void addStructInstruction( StructOperator op, @Nullable String typeName, @Nullable String fieldName, int javaCodePos, int lineNumber ) {
instructions.add( new WasmStructInstruction( op, typeName == null ? null : types.valueOf( typeName ), fieldName, javaCodePos ) ); instructions.add( new WasmStructInstruction( op, typeName == null ? null : types.valueOf( typeName ), fieldName, javaCodePos, lineNumber ) );
} }
} }

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -46,9 +45,11 @@ class WasmConstInstruction extends WasmInstruction {
* the data type of the number * the data type of the number
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmConstInstruction( Number value, ValueType valueType, int javaCodePos ) { WasmConstInstruction( Number value, ValueType valueType, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.value = value; this.value = value;
this.valueType = valueType; this.valueType = valueType;
} }
@ -60,9 +61,11 @@ class WasmConstInstruction extends WasmInstruction {
* the constant value * the constant value
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmConstInstruction( Number value, int javaCodePos ) { WasmConstInstruction( Number value, int javaCodePos, int lineNumber ) {
this( value, getValueType( value ), javaCodePos ); this( value, getValueType( value ), javaCodePos, lineNumber );
} }
/** /**

View File

@ -17,7 +17,6 @@ package de.inetsoftware.jwebassembly.module;
import java.io.IOException; import java.io.IOException;
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -38,9 +37,11 @@ class WasmConvertInstruction extends WasmInstruction {
* the conversion type * the conversion type
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmConvertInstruction( ValueTypeConvertion conversion, int javaCodePos ) { WasmConvertInstruction( ValueTypeConvertion conversion, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.conversion = conversion; this.conversion = conversion;
} }

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import de.inetsoftware.classparser.Member; import de.inetsoftware.classparser.Member;
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -46,9 +45,11 @@ class WasmGlobalInstruction extends WasmInstruction {
* reference to a static field * reference to a static field
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmGlobalInstruction( boolean load, Member ref, int javaCodePos ) { WasmGlobalInstruction( boolean load, Member ref, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.load = load; this.load = load;
this.ref = ref; this.ref = ref;
} }

View File

@ -38,20 +38,26 @@ abstract class WasmInstruction {
Const, Convert, Local, Global, Block, Numeric, Nop, Call, Array, Struct; Const, Convert, Local, Global, Block, Numeric, Nop, Call, Array, Struct;
} }
private int javaCodePos; private int javaCodePos;
private final int lineNumber;
/** /**
* Create a new instance of an instruction * Create a new instance of an instruction
* *
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmInstruction( int javaCodePos ) { WasmInstruction( int javaCodePos, int lineNumber ) {
this.javaCodePos = javaCodePos; this.javaCodePos = javaCodePos;
this.lineNumber = lineNumber;
} }
/** /**
* Get the type of instruction * Get the type of instruction
*
* @return the type * @return the type
*/ */
@Nonnull @Nonnull
@ -69,18 +75,30 @@ abstract class WasmInstruction {
/** /**
* Get current code position in Java method. * Get current code position in Java method.
*
* @return the position * @return the position
*/ */
int getCodePosition() { int getCodePosition() {
return javaCodePos; return javaCodePos;
} }
/**
* Get the line number in the Java source file
*
* @return the line number
*/
int getLineNumber() {
return lineNumber;
}
/** /**
* Set a new code position after reorganize the order * Set a new code position after reorganize the order
* @param newPos new position *
* @param newPos
* new position
*/ */
void setCodePosition( int newPos ) { void setCodePosition( int newPos ) {
this.javaCodePos = newPos; this.javaCodePos = newPos;
} }
/** /**

View File

@ -41,9 +41,11 @@ class WasmLoadStoreInstruction extends WasmLocalInstruction {
* the manager for local variables * the manager for local variables
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmLoadStoreInstruction( boolean load, @Nonnegative int idx, LocaleVariableManager localVariables, int javaCodePos ) { WasmLoadStoreInstruction( boolean load, @Nonnegative int idx, LocaleVariableManager localVariables, int javaCodePos, int lineNumber ) {
super( load, idx, javaCodePos ); super( load, idx, javaCodePos, lineNumber );
this.localVariables = localVariables; this.localVariables = localVariables;
} }

View File

@ -47,9 +47,11 @@ class WasmLocalInstruction extends WasmInstruction {
* the memory/slot idx of the variable * the memory/slot idx of the variable
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmLocalInstruction( boolean load, @Nonnegative int idx, int javaCodePos ) { WasmLocalInstruction( boolean load, @Nonnegative int idx, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.op = load ? get : set; this.op = load ? get : set;
this.idx = idx; this.idx = idx;
} }

View File

@ -20,7 +20,6 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
/** /**
@ -36,9 +35,11 @@ class WasmNopInstruction extends WasmInstruction {
* *
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmNopInstruction( int javaCodePos ) { WasmNopInstruction( int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
} }
/** /**

View File

@ -21,7 +21,6 @@ import java.io.IOException;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import de.inetsoftware.jwebassembly.module.WasmInstruction.Type;
import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.AnyType;
import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.NumericOperator;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
@ -47,9 +46,11 @@ class WasmNumericInstruction extends WasmInstruction {
* the type of the parameters * the type of the parameters
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmNumericInstruction( @Nullable NumericOperator numOp, @Nullable ValueType valueType, int javaCodePos ) { WasmNumericInstruction( @Nullable NumericOperator numOp, @Nullable ValueType valueType, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.numOp = numOp; this.numOp = numOp;
this.valueType = valueType; this.valueType = valueType;
} }

View File

@ -52,9 +52,11 @@ class WasmStructInstruction extends WasmInstruction {
* the name of field if needed for the operation * the name of field if needed for the operation
* @param javaCodePos * @param javaCodePos
* the code position/offset in the Java method * the code position/offset in the Java method
* @param lineNumber
* the line number in the Java source code
*/ */
WasmStructInstruction( @Nullable StructOperator op, @Nullable StructType type, @Nullable String fieldName, int javaCodePos ) { WasmStructInstruction( @Nullable StructOperator op, @Nullable StructType type, @Nullable String fieldName, int javaCodePos, int lineNumber ) {
super( javaCodePos ); super( javaCodePos, lineNumber );
this.op = op; this.op = op;
this.type = type; this.type = type;
this.fieldName = fieldName; this.fieldName = fieldName;

View File

@ -55,64 +55,64 @@ public class WatParser extends WasmCodeBuilder {
String tok = tokens.get( i ); String tok = tokens.get( i );
switch( tok ) { switch( tok ) {
case "local.get": case "local.get":
addLocalInstruction( true, getInt( tokens, ++i), javaCodePos ); addLocalInstruction( true, getInt( tokens, ++i), javaCodePos, lineNumber );
break; break;
case "local.set": case "local.set":
addLocalInstruction( false, getInt( tokens, ++i), javaCodePos ); addLocalInstruction( false, getInt( tokens, ++i), javaCodePos, lineNumber );
break; break;
// case "get_global": // case "get_global":
// addGlobalInstruction( true, ref, javaCodePos ); // addGlobalInstruction( true, ref, javaCodePos );
// break; // break;
case "i32.const": case "i32.const":
addConstInstruction( getInt( tokens, ++i), ValueType.i32, javaCodePos ); addConstInstruction( getInt( tokens, ++i), ValueType.i32, javaCodePos, lineNumber );
break; break;
case "i32.add": case "i32.add":
addNumericInstruction( NumericOperator.add, ValueType.i32, javaCodePos ); addNumericInstruction( NumericOperator.add, ValueType.i32, javaCodePos, lineNumber );
break; break;
case "i32.trunc_sat_f32_s": case "i32.trunc_sat_f32_s":
addConvertInstruction( ValueTypeConvertion.f2i, javaCodePos ); addConvertInstruction( ValueTypeConvertion.f2i, javaCodePos, lineNumber );
break; break;
case "i64.extend_i32_s": case "i64.extend_i32_s":
addConvertInstruction( ValueTypeConvertion.i2l, javaCodePos ); addConvertInstruction( ValueTypeConvertion.i2l, javaCodePos, lineNumber );
break; break;
case "i64.trunc_sat_f64_s": case "i64.trunc_sat_f64_s":
addConvertInstruction( ValueTypeConvertion.d2l, javaCodePos ); addConvertInstruction( ValueTypeConvertion.d2l, javaCodePos, lineNumber );
break; break;
case "f32.convert_i32_s": case "f32.convert_i32_s":
addConvertInstruction( ValueTypeConvertion.i2f, javaCodePos ); addConvertInstruction( ValueTypeConvertion.i2f, javaCodePos, lineNumber );
break; break;
case "f32.div": case "f32.div":
addNumericInstruction( NumericOperator.div, ValueType.f32, javaCodePos ); addNumericInstruction( NumericOperator.div, ValueType.f32, javaCodePos, lineNumber );
break; break;
case "f32.max": case "f32.max":
addNumericInstruction( NumericOperator.max, ValueType.f32, javaCodePos ); addNumericInstruction( NumericOperator.max, ValueType.f32, javaCodePos, lineNumber );
break; break;
case "f32.mul": case "f32.mul":
addNumericInstruction( NumericOperator.mul, ValueType.f32, javaCodePos ); addNumericInstruction( NumericOperator.mul, ValueType.f32, javaCodePos, lineNumber );
break; break;
case "f32.sub": case "f32.sub":
addNumericInstruction( NumericOperator.sub, ValueType.f32, javaCodePos ); addNumericInstruction( NumericOperator.sub, ValueType.f32, javaCodePos, lineNumber );
break; break;
case "f64.convert_i64_s": case "f64.convert_i64_s":
addConvertInstruction( ValueTypeConvertion.l2d, javaCodePos ); addConvertInstruction( ValueTypeConvertion.l2d, javaCodePos, lineNumber );
break; break;
case "f64.div": case "f64.div":
addNumericInstruction( NumericOperator.div, ValueType.f64, javaCodePos ); addNumericInstruction( NumericOperator.div, ValueType.f64, javaCodePos, lineNumber );
break; break;
case "f64.max": case "f64.max":
addNumericInstruction( NumericOperator.max, ValueType.f64, javaCodePos ); addNumericInstruction( NumericOperator.max, ValueType.f64, javaCodePos, lineNumber );
break; break;
case "f64.mul": case "f64.mul":
addNumericInstruction( NumericOperator.mul, ValueType.f64, javaCodePos ); addNumericInstruction( NumericOperator.mul, ValueType.f64, javaCodePos, lineNumber );
break; break;
case "f64.sub": case "f64.sub":
addNumericInstruction( NumericOperator.sub, ValueType.f64, javaCodePos ); addNumericInstruction( NumericOperator.sub, ValueType.f64, javaCodePos, lineNumber );
break; break;
// case "call": // case "call":
// addCallInstruction( method, javaCodePos ); // addCallInstruction( method, javaCodePos );
// break; // break;
case "return": case "return":
addBlockInstruction( WasmBlockOperator.RETURN, null, javaCodePos ); addBlockInstruction( WasmBlockOperator.RETURN, null, javaCodePos, lineNumber );
break; break;
default: default:
throw new WasmException( "Unknown WASM token: " + tok, lineNumber ); throw new WasmException( "Unknown WASM token: " + tok, lineNumber );