From 5e40f1603e087b6db26e445301fe15a882eb24a3 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sun, 31 Mar 2019 11:23:45 +0200 Subject: [PATCH] pass the line number to the parsed instructions for a source map generation #6 --- .../jwebassembly/module/BranchManger.java | 23 +- .../module/JavaMethodWasmCodeBuilder.java | 359 +++++++++--------- .../module/WasmArrayInstruction.java | 6 +- .../module/WasmBlockInstruction.java | 6 +- .../module/WasmCallInstruction.java | 6 +- .../jwebassembly/module/WasmCodeBuilder.java | 72 ++-- .../module/WasmConstInstruction.java | 13 +- .../module/WasmConvertInstruction.java | 7 +- .../module/WasmGlobalInstruction.java | 7 +- .../jwebassembly/module/WasmInstruction.java | 26 +- .../module/WasmLoadStoreInstruction.java | 6 +- .../module/WasmLocalInstruction.java | 6 +- .../module/WasmNopInstruction.java | 7 +- .../module/WasmNumericInstruction.java | 7 +- .../module/WasmStructInstruction.java | 6 +- .../jwebassembly/watparser/WatParser.java | 36 +- 16 files changed, 334 insertions(+), 259 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManger.java b/src/de/inetsoftware/jwebassembly/module/BranchManger.java index 3ea1641a..b81de367 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManger.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManger.java @@ -244,8 +244,8 @@ private void convertToLoop( ParsedBlock gotoBlock, int conditionStart, int condi gotoBlock.op = JavaBlockOperator.LOOP; gotoBlock.endPosition = conditionEnd; - instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) ); - instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) ); + instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew, gotoBlock.lineNumber ) ); + instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew, gotoBlock.lineNumber ) ); } /** @@ -743,15 +743,18 @@ boolean isCatch( int codePosition ) { void handle( CodeInputStream byteCode ) { int codePosition = -1; 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 ) { continue; } else { 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 @@ public boolean add( BranchNode e ) { * the target for instructions * @param idx * index in the current instruction + * @param lineNumber + * the line number in the Java source code * @return the new index in the instructions */ - int handle( int codePosition, List instructions, int idx ) { + int handle( int codePosition, List instructions, int idx, int lineNumber ) { if( codePosition < startPos || codePosition > endPos ) { return idx; } 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 ) { - idx = branch.handle( codePosition, instructions, idx ); + idx = branch.handle( codePosition, instructions, idx, lineNumber ); } if( codePosition == endPos && endOp != null ) { - instructions.add( idx++, new WasmBlockInstruction( endOp, null, codePosition ) ); + instructions.add( idx++, new WasmBlockInstruction( endOp, null, codePosition, lineNumber ) ); } return idx; } diff --git a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java index 4c1cde07..4db8ac0a 100644 --- a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java @@ -40,7 +40,7 @@ */ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { - private BranchManger branchManager = new BranchManger( getInstructions() ); + private BranchManger branchManager = new BranchManger( getInstructions() ); /** * Build the wasm instructions @@ -67,7 +67,6 @@ void buildCode( @Nonnull Code code, boolean hasReturn ) { } } - /** * Write the byte code of a method. * @@ -80,17 +79,18 @@ void buildCode( @Nonnull Code code, boolean hasReturn ) { * @throws WasmException * 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 { boolean wide = false; while( byteCode.available() > 0 ) { int codePos = byteCode.getCodePosition(); + int lineNumber = byteCode.getLineNumber(); int op = byteCode.readUnsignedByte(); switch( op ) { case 0: // nop break; case 1: // aconst_null - addStructInstruction( StructOperator.NULL, null, null, codePos ); + addStructInstruction( StructOperator.NULL, null, null, codePos, lineNumber ); break; case 2: // iconst_m1 case 3: // iconst_0 @@ -99,142 +99,142 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo case 6: // iconst_3 case 7: // iconst_4 case 8: // iconst_5 - addConstInstruction( Integer.valueOf( op - 3 ), ValueType.i32, codePos ); + addConstInstruction( Integer.valueOf( op - 3 ), ValueType.i32, codePos, lineNumber ); break; - case 9: // lconst_0 + case 9: // lconst_0 case 10: // lconst_1 - addConstInstruction( Long.valueOf( op - 9 ), ValueType.i64, codePos ); + addConstInstruction( Long.valueOf( op - 9 ), ValueType.i64, codePos, lineNumber ); break; case 11: // fconst_0 case 12: // fconst_1 case 13: // fconst_2 - addConstInstruction( Float.valueOf( op - 11 ), ValueType.f32, codePos ); + addConstInstruction( Float.valueOf( op - 11 ), ValueType.f32, codePos, lineNumber ); break; case 14: // dconst_0 case 15: // dconst_1 - addConstInstruction( Double.valueOf( op - 14 ), ValueType.f64, codePos ); + addConstInstruction( Double.valueOf( op - 14 ), ValueType.f64, codePos, lineNumber ); break; case 16: // bipush - addConstInstruction( Integer.valueOf( byteCode.readByte() ), ValueType.i32, codePos ); + addConstInstruction( Integer.valueOf( byteCode.readByte() ), ValueType.i32, codePos, lineNumber ); break; case 17: // sipush - addConstInstruction( Integer.valueOf( byteCode.readShort() ), ValueType.i32, codePos ); + addConstInstruction( Integer.valueOf( byteCode.readShort() ), ValueType.i32, codePos, lineNumber ); break; case 18: // ldc - addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedByte() ), codePos ); + addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedByte() ), codePos, lineNumber ); break; case 19: // ldc_w case 20: // ldc2_w - addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedShort() ), codePos ); + addConstInstruction( (Number)constantPool.get( byteCode.readUnsignedShort() ), codePos, lineNumber ); break; case 21: // iload - addLoadStoreInstruction( ValueType.i32, true, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.i32, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 22: // lload - addLoadStoreInstruction( ValueType.i64, true, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.i64, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 23: // fload - addLoadStoreInstruction( ValueType.f32, true, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.f32, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 24: // dload - addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 25: // aload - addLoadStoreInstruction( ValueType.anyref, true, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.anyref, true, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 26: // iload_0 case 27: // iload_1 case 28: // iload_2 case 29: // iload_3 - addLoadStoreInstruction( ValueType.i32, true, op - 26, codePos ); + addLoadStoreInstruction( ValueType.i32, true, op - 26, codePos, lineNumber ); break; case 30: // lload_0 case 31: // lload_1 case 32: // lload_2 case 33: // lload_3 - addLoadStoreInstruction( ValueType.i64, true, op - 30, codePos ); + addLoadStoreInstruction( ValueType.i64, true, op - 30, codePos, lineNumber ); break; case 34: // fload_0 case 35: // fload_1 case 36: // fload_2 case 37: // fload_3 - addLoadStoreInstruction( ValueType.f32, true, op - 34, codePos ); + addLoadStoreInstruction( ValueType.f32, true, op - 34, codePos, lineNumber ); break; case 38: // dload_0 case 39: // dload_1 case 40: // dload_2 case 41: // dload_3 - addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos ); + addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos, lineNumber ); break; case 42: //aload_0 case 43: //aload_1 case 44: //aload_2 case 45: //aload_3 - addLoadStoreInstruction( ValueType.anyref, true, op - 42, codePos ); + addLoadStoreInstruction( ValueType.anyref, true, op - 42, codePos, lineNumber ); break; case 46: // iaload - addArrayInstruction( ArrayOperator.GET, ValueType.i32, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.i32, codePos, lineNumber ); break; case 47: // laload - addArrayInstruction( ArrayOperator.GET, ValueType.i64, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.i64, codePos, lineNumber ); break; case 48: // faload - addArrayInstruction( ArrayOperator.GET, ValueType.f32, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.f32, codePos, lineNumber ); break; case 49: // daload - addArrayInstruction( ArrayOperator.GET, ValueType.f64, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.f64, codePos, lineNumber ); break; case 50: // aaload AnyType storeType = findPreviousPushInstructionPushValueType(); - addArrayInstruction( ArrayOperator.GET, storeType, codePos ); + addArrayInstruction( ArrayOperator.GET, storeType, codePos, lineNumber ); break; case 51: // baload - addArrayInstruction( ArrayOperator.GET, ValueType.i8, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.i8, codePos, lineNumber ); break; case 52: // caload - addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos, lineNumber ); break; case 53: // saload - addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos ); + addArrayInstruction( ArrayOperator.GET, ValueType.i16, codePos, lineNumber ); break; case 54: // istore - addLoadStoreInstruction( ValueType.i32, false, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.i32, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 55: // lstore - addLoadStoreInstruction( ValueType.i64, false, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.i64, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 56: // fstore - addLoadStoreInstruction( ValueType.f32, false, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.f32, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 57: // dstore - addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 58: // astore - addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedIndex( wide ), codePos ); + addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 59: // istore_0 case 60: // istore_1 case 61: // istore_2 case 62: // istore_3 - addLoadStoreInstruction( ValueType.i32, false, op - 59, codePos ); + addLoadStoreInstruction( ValueType.i32, false, op - 59, codePos, lineNumber ); break; case 63: // lstore_0 case 64: // lstore_1 case 65: // lstore_2 case 66: // lstore_3 - addLoadStoreInstruction( ValueType.i64, false, op - 63, codePos ); + addLoadStoreInstruction( ValueType.i64, false, op - 63, codePos, lineNumber ); break; case 67: // fstore_0 case 68: // fstore_1 case 69: // fstore_2 case 70: // fstore_3 - addLoadStoreInstruction( ValueType.f32, false, op - 67, codePos ); + addLoadStoreInstruction( ValueType.f32, false, op - 67, codePos, lineNumber ); break; case 71: // dstore_0 case 72: // dstore_1 case 73: // dstore_2 case 74: // dstore_3 - addLoadStoreInstruction( ValueType.f64, false, op - 71, codePos ); + addLoadStoreInstruction( ValueType.f64, false, op - 71, codePos, lineNumber ); break; case 75: // astore_0 case 76: // astore_1 @@ -245,41 +245,42 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo } else { storeType = findPreviousPushInstructionPushValueType(); } - addLoadStoreInstruction( storeType, false, op - 75, codePos ); + addLoadStoreInstruction( storeType, false, op - 75, codePos, lineNumber ); break; case 79: // iastore - addArrayInstruction( ArrayOperator.SET, ValueType.i32, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.i32, codePos, lineNumber ); break; case 80: // lastore - addArrayInstruction( ArrayOperator.SET, ValueType.i64, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.i64, codePos, lineNumber ); break; case 81: // fastore - addArrayInstruction( ArrayOperator.SET, ValueType.f32, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.f32, codePos, lineNumber ); break; case 82: // dastore - addArrayInstruction( ArrayOperator.SET, ValueType.f64, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.f64, codePos, lineNumber ); break; case 83: // aastore storeType = findPreviousPushInstructionPushValueType(); - addArrayInstruction( ArrayOperator.SET, storeType, codePos ); + addArrayInstruction( ArrayOperator.SET, storeType, codePos, lineNumber ); break; case 84: // bastore - addArrayInstruction( ArrayOperator.SET, ValueType.i8, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.i8, codePos, lineNumber ); break; case 85: // castore - addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos, lineNumber ); break; case 86: // sastore - addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos ); + addArrayInstruction( ArrayOperator.SET, ValueType.i16, codePos, lineNumber ); break; case 87: // pop case 88: // pop2 - addBlockInstruction( WasmBlockOperator.DROP, null, codePos ); + addBlockInstruction( WasmBlockOperator.DROP, null, codePos, lineNumber ); break; case 89: // dup: duplicate the value on top of the stack case 92: // dup2 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; case 90: // dup_x1 case 91: // dup_x2 @@ -287,237 +288,239 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo case 94: // dup2_x2 case 95: // swap // 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 - addNumericInstruction( NumericOperator.add, ValueType.i32, codePos); + addNumericInstruction( NumericOperator.add, ValueType.i32, codePos, lineNumber ); break; case 97: // ladd - addNumericInstruction( NumericOperator.add, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.add, ValueType.i64, codePos, lineNumber ); break; case 98: // fadd - addNumericInstruction( NumericOperator.add, ValueType.f32, codePos ); + addNumericInstruction( NumericOperator.add, ValueType.f32, codePos, lineNumber ); break; case 99: // dadd - addNumericInstruction( NumericOperator.add, ValueType.f64, codePos ); + addNumericInstruction( NumericOperator.add, ValueType.f64, codePos, lineNumber ); break; case 100: // isub - addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber ); break; case 101: // lsub - addNumericInstruction( NumericOperator.sub, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.sub, ValueType.i64, codePos, lineNumber ); break; case 102: // fsub - addNumericInstruction( NumericOperator.sub, ValueType.f32, codePos ); + addNumericInstruction( NumericOperator.sub, ValueType.f32, codePos, lineNumber ); break; case 103: // dsub - addNumericInstruction( NumericOperator.sub, ValueType.f64, codePos ); + addNumericInstruction( NumericOperator.sub, ValueType.f64, codePos, lineNumber ); break; case 104: // imul; - addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos, lineNumber ); break; case 105: // lmul - addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos, lineNumber ); break; case 106: // fmul - addNumericInstruction( NumericOperator.mul, ValueType.f32, codePos ); + addNumericInstruction( NumericOperator.mul, ValueType.f32, codePos, lineNumber ); break; case 107: // dmul - addNumericInstruction( NumericOperator.mul, ValueType.f64, codePos ); + addNumericInstruction( NumericOperator.mul, ValueType.f64, codePos, lineNumber ); break; case 108: // idiv - addNumericInstruction( NumericOperator.div, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.div, ValueType.i32, codePos, lineNumber ); break; case 109: // ldiv - addNumericInstruction( NumericOperator.div, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.div, ValueType.i64, codePos, lineNumber ); break; case 110: // fdiv - addNumericInstruction( NumericOperator.div, ValueType.f32, codePos ); + addNumericInstruction( NumericOperator.div, ValueType.f32, codePos, lineNumber ); break; case 111: // ddiv - addNumericInstruction( NumericOperator.div, ValueType.f64, codePos ); + addNumericInstruction( NumericOperator.div, ValueType.f64, codePos, lineNumber ); break; case 112: // irem - addNumericInstruction( NumericOperator.rem, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.rem, ValueType.i32, codePos, lineNumber ); break; case 113: // lrem - addNumericInstruction( NumericOperator.rem, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.rem, ValueType.i64, codePos, lineNumber ); break; case 114: // frem //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; case 115: // drem //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; case 116: // ineg - addConstInstruction( -1, ValueType.i32, codePos ); - addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos ); + addConstInstruction( -1, ValueType.i32, codePos, lineNumber ); + addNumericInstruction( NumericOperator.mul, ValueType.i32, codePos, lineNumber ); break; case 117: // lneg - addConstInstruction( (long)-1, ValueType.i64, codePos ); - addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos ); + addConstInstruction( (long)-1, ValueType.i64, codePos, lineNumber ); + addNumericInstruction( NumericOperator.mul, ValueType.i64, codePos, lineNumber ); break; case 118: // fneg - addNumericInstruction( NumericOperator.neg, ValueType.f32, codePos ); + addNumericInstruction( NumericOperator.neg, ValueType.f32, codePos, lineNumber ); break; case 119: // dneg - addNumericInstruction( NumericOperator.neg, ValueType.f64, codePos ); + addNumericInstruction( NumericOperator.neg, ValueType.f64, codePos, lineNumber ); break; case 120: // ishl - addNumericInstruction( NumericOperator.shl, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.shl, ValueType.i32, codePos, lineNumber ); break; case 121: // lshl - addConvertInstruction( ValueTypeConvertion.i2l, codePos ); // the shift parameter must be of type long!!! - addNumericInstruction( NumericOperator.shl, ValueType.i64, codePos ); + addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); // the shift parameter must be of type long!!! + addNumericInstruction( NumericOperator.shl, ValueType.i64, codePos, lineNumber ); break; case 122: // ishr - addNumericInstruction( NumericOperator.shr_s, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.shr_s, ValueType.i32, codePos, lineNumber ); break; case 123: // lshr - addConvertInstruction( ValueTypeConvertion.i2l, codePos ); // the shift parameter must be of type long!!! - addNumericInstruction( NumericOperator.shr_s, ValueType.i64, codePos ); + addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); // the shift parameter must be of type long!!! + addNumericInstruction( NumericOperator.shr_s, ValueType.i64, codePos, lineNumber ); break; case 124: // iushr - addNumericInstruction( NumericOperator.shr_u, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.shr_u, ValueType.i32, codePos, lineNumber ); break; case 125: // lushr - addConvertInstruction( ValueTypeConvertion.i2l, codePos ); // the shift parameter must be of type long!!! - addNumericInstruction( NumericOperator.shr_u, ValueType.i64, codePos ); + addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); // the shift parameter must be of type long!!! + addNumericInstruction( NumericOperator.shr_u, ValueType.i64, codePos, lineNumber ); break; case 126: // iand - addNumericInstruction( NumericOperator.and, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.and, ValueType.i32, codePos, lineNumber ); break; case 127: // land - addNumericInstruction( NumericOperator.and, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.and, ValueType.i64, codePos, lineNumber ); break; case 128: // ior - addNumericInstruction( NumericOperator.or, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.or, ValueType.i32, codePos, lineNumber ); break; case 129: // lor - addNumericInstruction( NumericOperator.or, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.or, ValueType.i64, codePos, lineNumber ); break; case 130: // ixor - addNumericInstruction( NumericOperator.xor, ValueType.i32, codePos ); + addNumericInstruction( NumericOperator.xor, ValueType.i32, codePos, lineNumber ); break; case 131: // lxor - addNumericInstruction( NumericOperator.xor, ValueType.i64, codePos ); + addNumericInstruction( NumericOperator.xor, ValueType.i64, codePos, lineNumber ); break; case 132: // iinc int idx = byteCode.readUnsignedIndex( wide ); - addLoadStoreInstruction( ValueType.i32, true, idx, codePos ); - addConstInstruction( (int)(wide ? byteCode.readShort() : byteCode.readByte()), ValueType.i32, codePos ); - addNumericInstruction( NumericOperator.add, ValueType.i32, codePos); - addLoadStoreInstruction( ValueType.i32, false, idx, codePos ); + addLoadStoreInstruction( ValueType.i32, true, idx, codePos, lineNumber ); + addConstInstruction( (int)(wide ? byteCode.readShort() : byteCode.readByte()), ValueType.i32, codePos, lineNumber ); + addNumericInstruction( NumericOperator.add, ValueType.i32, codePos, lineNumber ); + addLoadStoreInstruction( ValueType.i32, false, idx, codePos, lineNumber ); break; case 133: // i2l - addConvertInstruction( ValueTypeConvertion.i2l, codePos ); + addConvertInstruction( ValueTypeConvertion.i2l, codePos, lineNumber ); break; case 134: // i2f - addConvertInstruction( ValueTypeConvertion.i2f, codePos ); + addConvertInstruction( ValueTypeConvertion.i2f, codePos, lineNumber ); break; case 135: // i2d - addConvertInstruction( ValueTypeConvertion.i2d, codePos ); + addConvertInstruction( ValueTypeConvertion.i2d, codePos, lineNumber ); break; case 136: // l2i - addConvertInstruction( ValueTypeConvertion.l2i, codePos ); + addConvertInstruction( ValueTypeConvertion.l2i, codePos, lineNumber ); break; case 137: // l2f - addConvertInstruction( ValueTypeConvertion.l2f, codePos ); + addConvertInstruction( ValueTypeConvertion.l2f, codePos, lineNumber ); break; case 138: // l2d - addConvertInstruction( ValueTypeConvertion.l2d, codePos ); + addConvertInstruction( ValueTypeConvertion.l2d, codePos, lineNumber ); break; case 139: // f2i - addConvertInstruction( ValueTypeConvertion.f2i, codePos ); + addConvertInstruction( ValueTypeConvertion.f2i, codePos, lineNumber ); break; case 140: // f2l - addConvertInstruction( ValueTypeConvertion.f2l, codePos ); + addConvertInstruction( ValueTypeConvertion.f2l, codePos, lineNumber ); break; case 141: // f2d - addConvertInstruction( ValueTypeConvertion.f2d, codePos ); + addConvertInstruction( ValueTypeConvertion.f2d, codePos, lineNumber ); break; case 142: // d2i - addConvertInstruction( ValueTypeConvertion.d2i, codePos ); + addConvertInstruction( ValueTypeConvertion.d2i, codePos, lineNumber ); break; case 143: // d2l - addConvertInstruction( ValueTypeConvertion.d2l, codePos ); + addConvertInstruction( ValueTypeConvertion.d2l, codePos, lineNumber ); break; case 144: // d2f - addConvertInstruction( ValueTypeConvertion.d2f, codePos ); + addConvertInstruction( ValueTypeConvertion.d2f, codePos, lineNumber ); break; case 145: // i2b - addConvertInstruction( ValueTypeConvertion.i2b, codePos ); + addConvertInstruction( ValueTypeConvertion.i2b, codePos, lineNumber ); break; case 146: // i2c - addConstInstruction( 0xFFFF, ValueType.i32, codePos ); - addNumericInstruction( NumericOperator.and, ValueType.i32, codePos ); + addConstInstruction( 0xFFFF, ValueType.i32, codePos, lineNumber ); + addNumericInstruction( NumericOperator.and, ValueType.i32, codePos, lineNumber ); break; case 147: // i2s - addConvertInstruction( ValueTypeConvertion.i2s, codePos ); + addConvertInstruction( ValueTypeConvertion.i2s, codePos, lineNumber ); break; case 148: // lcmp - opCompare( ValueType.i64, byteCode, codePos ); + opCompare( ValueType.i64, byteCode, codePos, lineNumber ); break; case 149: // fcmpl case 150: // fcmpg - opCompare( ValueType.f32, byteCode, codePos ); + opCompare( ValueType.f32, byteCode, codePos, lineNumber ); break; case 151: // dcmpl case 152: // dcmpg - opCompare( ValueType.f64, byteCode, codePos ); + opCompare( ValueType.f64, byteCode, codePos, lineNumber ); break; case 153: // ifeq - opIfCondition( NumericOperator.eq, byteCode, codePos ); + opIfCondition( NumericOperator.eq, byteCode, codePos, lineNumber ); break; case 154: // ifne - opIfCondition( NumericOperator.ne, byteCode, codePos ); + opIfCondition( NumericOperator.ne, byteCode, codePos, lineNumber ); break; case 155: // iflt - opIfCondition( NumericOperator.lt, byteCode, codePos ); + opIfCondition( NumericOperator.lt, byteCode, codePos, lineNumber ); break; case 156: // ifge - opIfCondition( NumericOperator.ge, byteCode, codePos ); + opIfCondition( NumericOperator.ge, byteCode, codePos, lineNumber ); break; case 157: // ifgt - opIfCondition( NumericOperator.gt, byteCode, codePos ); + opIfCondition( NumericOperator.gt, byteCode, codePos, lineNumber ); break; case 158: // ifle - opIfCondition( NumericOperator.le, byteCode, codePos ); + opIfCondition( NumericOperator.le, byteCode, codePos, lineNumber ); break; case 159: // if_icmpeq - opIfCompareCondition( NumericOperator.eq, byteCode, codePos ); + opIfCompareCondition( NumericOperator.eq, byteCode, codePos, lineNumber ); break; case 160: // if_icmpne - opIfCompareCondition( NumericOperator.ne, byteCode, codePos ); + opIfCompareCondition( NumericOperator.ne, byteCode, codePos, lineNumber ); break; case 161: // if_icmplt - opIfCompareCondition( NumericOperator.lt, byteCode, codePos ); + opIfCompareCondition( NumericOperator.lt, byteCode, codePos, lineNumber ); break; case 162: // if_icmpge - opIfCompareCondition( NumericOperator.ge, byteCode, codePos ); + opIfCompareCondition( NumericOperator.ge, byteCode, codePos, lineNumber ); break; case 163: // if_icmpgt - opIfCompareCondition( NumericOperator.gt, byteCode, codePos ); + opIfCompareCondition( NumericOperator.gt, byteCode, codePos, lineNumber ); break; case 164: // if_icmple - opIfCompareCondition( NumericOperator.le, byteCode, codePos ); + opIfCompareCondition( NumericOperator.le, byteCode, codePos, lineNumber ); break; case 165: // if_acmpeq - opIfCompareCondition( NumericOperator.ref_eq, byteCode, codePos ); + opIfCompareCondition( NumericOperator.ref_eq, byteCode, codePos, lineNumber ); break; case 166: // if_acmpne - opIfCompareCondition( NumericOperator.ref_ne, byteCode, codePos ); + opIfCompareCondition( NumericOperator.ref_ne, byteCode, codePos, lineNumber ); break; case 167: // goto int offset = byteCode.readShort(); - branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), byteCode.getLineNumber() ); - addNopInstruction( codePos ); // marker of the line number for the branch manager + branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), lineNumber ); + addNopInstruction( codePos, lineNumber ); // marker of the line number for the branch manager break; case 168: // jsr case 169: // ret 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 171: // lookupswitch writeSwitchCode( byteCode, op == 171 ); @@ -529,7 +532,7 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo case 176: // areturn case 177: // return void ValueType type = null; - switch ( op ) { + switch( op ) { case 172: // ireturn type = ValueType.i32; break; @@ -546,43 +549,43 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo type = ValueType.anyref; break; } - addBlockInstruction( WasmBlockOperator.RETURN, type, codePos ); + addBlockInstruction( WasmBlockOperator.RETURN, type, codePos, lineNumber ); break; case 178: // getstatic ConstantRef ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); - addGlobalInstruction( true, ref, codePos ); + addGlobalInstruction( true, ref, codePos, lineNumber ); break; case 179: // putstatic ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); - addGlobalInstruction( false, ref, codePos ); + addGlobalInstruction( false, ref, codePos, lineNumber ); break; case 180: // getfield ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); - addStructInstruction( StructOperator.GET, ref.getClassName(), ref.getName(), codePos ); + addStructInstruction( StructOperator.GET, ref.getClassName(), ref.getName(), codePos, lineNumber ); break; case 181: // putfield ref = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() ); - addStructInstruction( StructOperator.SET, ref.getClassName(), ref.getName(), codePos ); + addStructInstruction( StructOperator.SET, ref.getClassName(), ref.getName(), codePos, lineNumber ); break; case 182: // invokevirtual case 183: // invokespecial, invoke a constructor case 184: // invokestatic idx = byteCode.readUnsignedShort(); ref = (ConstantRef)constantPool.get( idx ); - addCallInstruction( new FunctionName( ref ), codePos ); + addCallInstruction( new FunctionName( ref ), codePos, lineNumber ); break; //TODO case 185: // invokeinterface //TODO case 186: // invokedynamic case 187: // new String name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName(); - addStructInstruction( StructOperator.NEW_DEFAULT, name, null, codePos ); + addStructInstruction( StructOperator.NEW_DEFAULT, name, null, codePos, lineNumber ); break; case 188: // newarray int typeValue = byteCode.readByte(); switch( typeValue ) { case 4: // boolean case 5: // char - type = ValueType.i32; + type = ValueType.i32; break; case 6: //float type = ValueType.f32; @@ -599,28 +602,28 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo type = ValueType.i64; break; 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; case 189: // anewarray name = ((ConstantClass)constantPool.get( byteCode.readUnsignedShort() )).getName(); 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; case 190: // arraylength - addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos ); + addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos, lineNumber ); break; case 191: // athrow - addBlockInstruction( WasmBlockOperator.THROW, null, codePos ); + addBlockInstruction( WasmBlockOperator.THROW, null, codePos, lineNumber ); break; //TODO case 192: // checkcast //TODO case 193: // instanceof case 194: // monitorenter - addBlockInstruction( WasmBlockOperator.MONITOR_ENTER, null, codePos ); + addBlockInstruction( WasmBlockOperator.MONITOR_ENTER, null, codePos, lineNumber ); break; case 195: // monitorexit - addBlockInstruction( WasmBlockOperator.MONITOR_EXIT, null, codePos ); + addBlockInstruction( WasmBlockOperator.MONITOR_EXIT, null, codePos, lineNumber ); break; case 196: // wide // https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.wide @@ -628,18 +631,18 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo continue; //TODO case 197: // multianewarray case 198: // ifnull - opIfCompareCondition( NumericOperator.ifnull, byteCode, codePos ); + opIfCompareCondition( NumericOperator.ifnull, byteCode, codePos, lineNumber ); break; case 199: // ifnonnull - opIfCompareCondition( NumericOperator.ifnonnull, byteCode, codePos ); + opIfCompareCondition( NumericOperator.ifnonnull, byteCode, codePos, lineNumber ); break; case 200: // goto_w offset = byteCode.readInt(); - branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), byteCode.getLineNumber() ); - addNopInstruction( codePos ); // marker of the line number for the branch manager + branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), lineNumber ); + addNopInstruction( codePos, lineNumber ); // marker of the line number for the branch manager break; default: - throw new WasmException( "Unimplemented Java byte code operation: " + op, byteCode.getLineNumber() ); + throw new WasmException( "Unimplemented Java byte code operation: " + op, lineNumber ); } wide = false; } @@ -649,7 +652,7 @@ private void writeCode( CodeInputStream byteCode, ConstantPool constantPool, boo // 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 // 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 ) { throw ex; @@ -694,7 +697,7 @@ private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) int block = 0; int defaultBlock = -1; int currentPos = -1; - addLoadStoreInstruction( ValueType.i32, false, tempI32, codePos ); + addLoadStoreInstruction( ValueType.i32, false, tempI32, codePos, lineNumber ); do { int nextPos = findNext( currentPos, positions ); if( nextPos == currentPos ) { @@ -711,10 +714,10 @@ private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) } for( int i = 0; i < positions.length; i++ ) { if( positions[i] == currentPos ) { - addLoadStoreInstruction( ValueType.i32, true, tempI32, codePos ); - addConstInstruction( keys[i], ValueType.i32, codePos ); - addNumericInstruction( NumericOperator.eq, ValueType.i32, codePos ); - addBlockInstruction( WasmBlockOperator.BR_IF, block, codePos ); + addLoadStoreInstruction( ValueType.i32, true, tempI32, codePos, lineNumber ); + addConstInstruction( keys[i], ValueType.i32, codePos, lineNumber ); + addNumericInstruction( NumericOperator.eq, ValueType.i32, codePos, lineNumber ); + addBlockInstruction( WasmBlockOperator.BR_IF, block, codePos, lineNumber ); } } block++; @@ -722,7 +725,7 @@ private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) if( defaultBlock < 0 ) { defaultBlock = block; } - addBlockInstruction( WasmBlockOperator.BR, defaultBlock, codePos ); + addBlockInstruction( WasmBlockOperator.BR, defaultBlock, codePos, lineNumber ); } else { int low = byteCode.readInt(); keys = null; @@ -732,8 +735,8 @@ private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) 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 - addConstInstruction( low, ValueType.i32, codePos ); - addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos ); + addConstInstruction( low, ValueType.i32, codePos, lineNumber ); + addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber ); } } branchManager.addSwitchOperator( switchValuestartPosition, 0, lineNumber, keys, positions, defaultPosition ); @@ -810,38 +813,42 @@ private static int findNext( int current, int[] values ) { * Handle the if 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 * need to use condition for the if block. The caller of the method must already negate this + * * @param compareOp * The condition for the continue of a loop. * @param byteCode * current byte code stream to read the target offset. * @param codePos * the code position/offset in the Java method - * + * @param lineNumber + * the line number in the Java source code * @throws IOException * if any I/O errors occur. */ - private void opIfCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos ) throws IOException { - addConstInstruction( 0, ValueType.i32, codePos ); - opIfCompareCondition( compareOp, byteCode, codePos ); + private void opIfCondition( NumericOperator compareOp, CodeInputStream byteCode, int codePos, int lineNumber ) throws IOException { + addConstInstruction( 0, ValueType.i32, codePos, lineNumber ); + opIfCompareCondition( compareOp, byteCode, codePos, lineNumber ); } /** - * Handle the if of the Java byte code. This Java instruction compare 2 values from stack. - * Important: In the Java IF expression the condition for the jump to the else block is saved. In WebAssembler we need to use + * Handle the if of the Java byte code. This Java instruction compare 2 values from stack. 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. + * * @param compareOp * The condition for the continue of a loop. * @param byteCode * current byte code stream to read the target offset. * @param codePos * the code position/offset in the Java method - * + * @param lineNumber + * the line number in the Java source code * @throws IOException * 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(); - WasmNumericInstruction compare = new WasmNumericInstruction( compareOp, ValueType.i32, codePos ); + WasmNumericInstruction compare = new WasmNumericInstruction( compareOp, ValueType.i32, codePos, lineNumber ); branchManager.addIfOperator( codePos, offset, byteCode.getLineNumber(), compare ); getInstructions().add( compare ); } @@ -856,14 +863,16 @@ private void opIfCompareCondition( NumericOperator compareOp, CodeInputStream by * current byte code stream to read the next operation. * @param codePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code * @throws IOException * 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(); NumericOperator numOp; int nextOp = byteCode.read(); - switch( nextOp ){ + switch( nextOp ) { case 153: // ifeq numOp = NumericOperator.eq; break; @@ -886,7 +895,7 @@ private void opCompare( ValueType valueType, CodeInputStream byteCode, int codeP throw new WasmException( "Unexpected compare sub operation: " + nextOp, -1 ); } 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 ); getInstructions().add( compare ); } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java index 75b0a40e..a0f06cfd 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java @@ -47,9 +47,11 @@ class WasmArrayInstruction extends WasmInstruction { * the type of the parameters * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmArrayInstruction( @Nullable ArrayOperator op, @Nullable AnyType type, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.op = op; this.type = type; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java index 9d5ea969..490a9246 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java @@ -46,9 +46,11 @@ class WasmBlockInstruction extends WasmInstruction { * extra data depending of the operator * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmBlockInstruction( @Nonnull WasmBlockOperator op, @Nullable Object data, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.op = op; this.data = data; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCallInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmCallInstruction.java index 609b28b9..142e34e1 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCallInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCallInstruction.java @@ -44,9 +44,11 @@ class WasmCallInstruction extends WasmInstruction { * the function name that should be called * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ - WasmCallInstruction( FunctionName name, int javaCodePos ) { - super( javaCodePos ); + WasmCallInstruction( FunctionName name, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.name = name; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 8a4a5b80..14910be7 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -113,11 +113,13 @@ protected void calculateVariables() { * the memory/slot index of the variable in Java byte code * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ @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 ); - instructions.add( new WasmLoadStoreInstruction( load, javaIdx, localVariables, javaCodePos ) ); + instructions.add( new WasmLoadStoreInstruction( load, javaIdx, localVariables, javaCodePos, lineNumber ) ); } /** @@ -129,10 +131,12 @@ protected void addLoadStoreInstruction( AnyType valueType, boolean load, @Nonneg * the index of the variable * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ @Nonnull - protected void addLocalInstruction( boolean load, @Nonnegative int wasmIdx, int javaCodePos ) { - instructions.add( new WasmLocalInstruction( load, wasmIdx, javaCodePos ) ); + protected void addLocalInstruction( boolean load, @Nonnegative int wasmIdx, int javaCodePos, int lineNumber ) { + instructions.add( new WasmLocalInstruction( load, wasmIdx, javaCodePos, lineNumber ) ); } /** @@ -144,9 +148,11 @@ protected void addLocalInstruction( boolean load, @Nonnegative int wasmIdx, int * reference to a static field * @param javaCodePos * 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 ) { - instructions.add( new WasmGlobalInstruction( load, ref, javaCodePos ) ); + protected void addGlobalInstruction( boolean load, Member ref, int javaCodePos, int lineNumber ) { + instructions.add( new WasmGlobalInstruction( load, ref, javaCodePos, lineNumber ) ); } /** @@ -158,9 +164,11 @@ protected void addGlobalInstruction( boolean load, Member ref, int javaCodePos ) * the value type * @param javaCodePos * 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 ) { - instructions.add( new WasmConstInstruction( value, valueType, javaCodePos ) ); + protected void addConstInstruction( Number value, ValueType valueType, int javaCodePos, int lineNumber ) { + instructions.add( new WasmConstInstruction( value, valueType, javaCodePos, lineNumber ) ); } /** @@ -170,9 +178,11 @@ protected void addConstInstruction( Number value, ValueType valueType, int javaC * the value * @param javaCodePos * 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 ) { - instructions.add( new WasmConstInstruction( value, javaCodePos ) ); + protected void addConstInstruction( Number value, int javaCodePos, int lineNumber ) { + instructions.add( new WasmConstInstruction( value, javaCodePos, lineNumber ) ); } /** @@ -184,9 +194,11 @@ protected void addConstInstruction( Number value, int javaCodePos ) { * the value type * @param javaCodePos * 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 ) { - instructions.add( new WasmNumericInstruction( numOp, valueType, javaCodePos ) ); + protected void addNumericInstruction( @Nullable NumericOperator numOp, @Nullable ValueType valueType, int javaCodePos, int lineNumber ) { + instructions.add( new WasmNumericInstruction( numOp, valueType, javaCodePos, lineNumber ) ); } /** @@ -196,9 +208,11 @@ protected void addNumericInstruction( @Nullable NumericOperator numOp, @Nullable * the conversion * @param javaCodePos * 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 ) { - instructions.add( new WasmConvertInstruction( conversion, javaCodePos ) ); + protected void addConvertInstruction( ValueTypeConvertion conversion, int javaCodePos, int lineNumber ) { + instructions.add( new WasmConvertInstruction( conversion, javaCodePos, lineNumber ) ); } /** @@ -208,9 +222,11 @@ protected void addConvertInstruction( ValueTypeConvertion conversion, int javaCo * the function name that should be called * @param javaCodePos * 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 ) { - instructions.add( new WasmCallInstruction( name, javaCodePos ) ); + protected void addCallInstruction( FunctionName name, int javaCodePos, int lineNumber ) { + instructions.add( new WasmCallInstruction( name, javaCodePos, lineNumber ) ); } /** @@ -222,9 +238,11 @@ protected void addCallInstruction( FunctionName name, int javaCodePos ) { * extra data for some operations * @param javaCodePos * 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 ) { - instructions.add( new WasmBlockInstruction( op, data, javaCodePos ) ); + protected void addBlockInstruction( WasmBlockOperator op, @Nullable Object data, int javaCodePos, int lineNumber ) { + instructions.add( new WasmBlockInstruction( op, data, javaCodePos, lineNumber ) ); } /** @@ -233,9 +251,11 @@ protected void addBlockInstruction( WasmBlockOperator op, @Nullable Object data, * * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ - protected void addNopInstruction( int javaCodePos ) { - instructions.add( new WasmNopInstruction( javaCodePos ) ); + protected void addNopInstruction( int javaCodePos, int lineNumber ) { + instructions.add( new WasmNopInstruction( javaCodePos, lineNumber ) ); } /** @@ -247,9 +267,11 @@ protected void addNopInstruction( int javaCodePos ) { * the array type * @param javaCodePos * 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 ) { - instructions.add( new WasmArrayInstruction( op, type, javaCodePos ) ); + protected void addArrayInstruction( ArrayOperator op, AnyType type, int javaCodePos, int lineNumber ) { + instructions.add( new WasmArrayInstruction( op, type, javaCodePos, lineNumber ) ); } /** @@ -263,8 +285,10 @@ protected void addArrayInstruction( ArrayOperator op, AnyType type, int javaCode * the name of field if needed for the operation * @param javaCodePos * 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 ) { - instructions.add( new WasmStructInstruction( op, typeName == null ? null : types.valueOf( typeName ), fieldName, 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, lineNumber ) ); } } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmConstInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmConstInstruction.java index f831ada1..8fdff860 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmConstInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmConstInstruction.java @@ -21,7 +21,6 @@ import javax.annotation.Nonnull; import de.inetsoftware.jwebassembly.WasmException; -import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ValueType; @@ -46,9 +45,11 @@ class WasmConstInstruction extends WasmInstruction { * the data type of the number * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmConstInstruction( Number value, ValueType valueType, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.value = value; this.valueType = valueType; } @@ -60,9 +61,11 @@ class WasmConstInstruction extends WasmInstruction { * the constant value * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ - WasmConstInstruction( Number value, int javaCodePos ) { - this( value, getValueType( value ), javaCodePos ); + WasmConstInstruction( Number value, int javaCodePos, int lineNumber ) { + this( value, getValueType( value ), javaCodePos, lineNumber ); } /** diff --git a/src/de/inetsoftware/jwebassembly/module/WasmConvertInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmConvertInstruction.java index 5b0f5161..af90fd33 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmConvertInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmConvertInstruction.java @@ -17,7 +17,6 @@ import java.io.IOException; -import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ValueType; @@ -38,9 +37,11 @@ class WasmConvertInstruction extends WasmInstruction { * the conversion type * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ - WasmConvertInstruction( ValueTypeConvertion conversion, int javaCodePos ) { - super( javaCodePos ); + WasmConvertInstruction( ValueTypeConvertion conversion, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.conversion = conversion; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmGlobalInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmGlobalInstruction.java index 321cf531..5876dfcd 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmGlobalInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmGlobalInstruction.java @@ -21,7 +21,6 @@ import javax.annotation.Nonnull; import de.inetsoftware.classparser.Member; -import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ValueType; @@ -46,9 +45,11 @@ class WasmGlobalInstruction extends WasmInstruction { * reference to a static field * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmGlobalInstruction( boolean load, Member ref, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.load = load; this.ref = ref; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java index 48bd8fd2..ef9c471f 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmInstruction.java @@ -38,20 +38,26 @@ static enum Type { 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 * * @param javaCodePos * 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.lineNumber = lineNumber; } /** * Get the type of instruction + * * @return the type */ @Nonnull @@ -69,18 +75,30 @@ static enum Type { /** * Get current code position in Java method. + * * @return the position */ int getCodePosition() { 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 - * @param newPos new position + * + * @param newPos + * new position */ void setCodePosition( int newPos ) { - this.javaCodePos = newPos; + this.javaCodePos = newPos; } /** diff --git a/src/de/inetsoftware/jwebassembly/module/WasmLoadStoreInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmLoadStoreInstruction.java index 12c62ca6..8dfe76ea 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmLoadStoreInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmLoadStoreInstruction.java @@ -41,9 +41,11 @@ class WasmLoadStoreInstruction extends WasmLocalInstruction { * the manager for local variables * @param javaCodePos * 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 ) { - super( load, idx, javaCodePos ); + WasmLoadStoreInstruction( boolean load, @Nonnegative int idx, LocaleVariableManager localVariables, int javaCodePos, int lineNumber ) { + super( load, idx, javaCodePos, lineNumber ); this.localVariables = localVariables; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmLocalInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmLocalInstruction.java index f425e5c8..f23355da 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmLocalInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmLocalInstruction.java @@ -47,9 +47,11 @@ class WasmLocalInstruction extends WasmInstruction { * the memory/slot idx of the variable * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmLocalInstruction( boolean load, @Nonnegative int idx, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.op = load ? get : set; this.idx = idx; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmNopInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmNopInstruction.java index da74c6e6..042e0580 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmNopInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmNopInstruction.java @@ -20,7 +20,6 @@ import javax.annotation.Nonnull; -import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; /** @@ -36,9 +35,11 @@ class WasmNopInstruction extends WasmInstruction { * * @param javaCodePos * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code */ - WasmNopInstruction( int javaCodePos ) { - super( javaCodePos ); + WasmNopInstruction( int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); } /** diff --git a/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java index 9cbff718..4d6b326b 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmNumericInstruction.java @@ -21,7 +21,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.NumericOperator; import de.inetsoftware.jwebassembly.wasm.ValueType; @@ -47,9 +46,11 @@ class WasmNumericInstruction extends WasmInstruction { * the type of the parameters * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmNumericInstruction( @Nullable NumericOperator numOp, @Nullable ValueType valueType, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.numOp = numOp; this.valueType = valueType; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java index 58e259a0..8439c506 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java @@ -52,9 +52,11 @@ class WasmStructInstruction extends WasmInstruction { * the name of field if needed for the operation * @param javaCodePos * 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 ) { - super( javaCodePos ); + WasmStructInstruction( @Nullable StructOperator op, @Nullable StructType type, @Nullable String fieldName, int javaCodePos, int lineNumber ) { + super( javaCodePos, lineNumber ); this.op = op; this.type = type; this.fieldName = fieldName; diff --git a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java index 3a508ac8..5ced1f02 100644 --- a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java +++ b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java @@ -55,64 +55,64 @@ public void parse( String wat, int lineNumber ) { String tok = tokens.get( i ); switch( tok ) { case "local.get": - addLocalInstruction( true, getInt( tokens, ++i), javaCodePos ); + addLocalInstruction( true, getInt( tokens, ++i), javaCodePos, lineNumber ); break; case "local.set": - addLocalInstruction( false, getInt( tokens, ++i), javaCodePos ); + addLocalInstruction( false, getInt( tokens, ++i), javaCodePos, lineNumber ); break; // case "get_global": // addGlobalInstruction( true, ref, javaCodePos ); // break; case "i32.const": - addConstInstruction( getInt( tokens, ++i), ValueType.i32, javaCodePos ); + addConstInstruction( getInt( tokens, ++i), ValueType.i32, javaCodePos, lineNumber ); break; case "i32.add": - addNumericInstruction( NumericOperator.add, ValueType.i32, javaCodePos ); + addNumericInstruction( NumericOperator.add, ValueType.i32, javaCodePos, lineNumber ); break; case "i32.trunc_sat_f32_s": - addConvertInstruction( ValueTypeConvertion.f2i, javaCodePos ); + addConvertInstruction( ValueTypeConvertion.f2i, javaCodePos, lineNumber ); break; case "i64.extend_i32_s": - addConvertInstruction( ValueTypeConvertion.i2l, javaCodePos ); + addConvertInstruction( ValueTypeConvertion.i2l, javaCodePos, lineNumber ); break; case "i64.trunc_sat_f64_s": - addConvertInstruction( ValueTypeConvertion.d2l, javaCodePos ); + addConvertInstruction( ValueTypeConvertion.d2l, javaCodePos, lineNumber ); break; case "f32.convert_i32_s": - addConvertInstruction( ValueTypeConvertion.i2f, javaCodePos ); + addConvertInstruction( ValueTypeConvertion.i2f, javaCodePos, lineNumber ); break; case "f32.div": - addNumericInstruction( NumericOperator.div, ValueType.f32, javaCodePos ); + addNumericInstruction( NumericOperator.div, ValueType.f32, javaCodePos, lineNumber ); break; case "f32.max": - addNumericInstruction( NumericOperator.max, ValueType.f32, javaCodePos ); + addNumericInstruction( NumericOperator.max, ValueType.f32, javaCodePos, lineNumber ); break; case "f32.mul": - addNumericInstruction( NumericOperator.mul, ValueType.f32, javaCodePos ); + addNumericInstruction( NumericOperator.mul, ValueType.f32, javaCodePos, lineNumber ); break; case "f32.sub": - addNumericInstruction( NumericOperator.sub, ValueType.f32, javaCodePos ); + addNumericInstruction( NumericOperator.sub, ValueType.f32, javaCodePos, lineNumber ); break; case "f64.convert_i64_s": - addConvertInstruction( ValueTypeConvertion.l2d, javaCodePos ); + addConvertInstruction( ValueTypeConvertion.l2d, javaCodePos, lineNumber ); break; case "f64.div": - addNumericInstruction( NumericOperator.div, ValueType.f64, javaCodePos ); + addNumericInstruction( NumericOperator.div, ValueType.f64, javaCodePos, lineNumber ); break; case "f64.max": - addNumericInstruction( NumericOperator.max, ValueType.f64, javaCodePos ); + addNumericInstruction( NumericOperator.max, ValueType.f64, javaCodePos, lineNumber ); break; case "f64.mul": - addNumericInstruction( NumericOperator.mul, ValueType.f64, javaCodePos ); + addNumericInstruction( NumericOperator.mul, ValueType.f64, javaCodePos, lineNumber ); break; case "f64.sub": - addNumericInstruction( NumericOperator.sub, ValueType.f64, javaCodePos ); + addNumericInstruction( NumericOperator.sub, ValueType.f64, javaCodePos, lineNumber ); break; // case "call": // addCallInstruction( method, javaCodePos ); // break; case "return": - addBlockInstruction( WasmBlockOperator.RETURN, null, javaCodePos ); + addBlockInstruction( WasmBlockOperator.RETURN, null, javaCodePos, lineNumber ); break; default: throw new WasmException( "Unknown WASM token: " + tok, lineNumber );