mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
Finish refactoring with an intermediate model in the memory of WASM instructions.
This commit is contained in:
parent
d81da1f342
commit
3a74ebbe20
@ -21,6 +21,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnegative;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import de.inetsoftware.classparser.ClassFile;
|
import de.inetsoftware.classparser.ClassFile;
|
||||||
@ -163,9 +164,6 @@ public class ModuleGenerator {
|
|||||||
localVariables.reset();
|
localVariables.reset();
|
||||||
stackManager.reset();
|
stackManager.reset();
|
||||||
branchManager.reset();
|
branchManager.reset();
|
||||||
byteCode = code.getByteCode();
|
|
||||||
prepareCodeChunk( byteCode, method.getConstantPool() );
|
|
||||||
branchManager.calculate();
|
|
||||||
|
|
||||||
byteCode = code.getByteCode();
|
byteCode = code.getByteCode();
|
||||||
writeCode( byteCode, method.getConstantPool() );
|
writeCode( byteCode, method.getConstantPool() );
|
||||||
@ -272,247 +270,6 @@ public class ModuleGenerator {
|
|||||||
throw new WasmException( "Not supported Java data type in method signature: " + javaType, sourceFile, -1 );
|
throw new WasmException( "Not supported Java data type in method signature: " + javaType, sourceFile, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Analyze and prepare a chunk of byte code.
|
|
||||||
*
|
|
||||||
* @param byteCode
|
|
||||||
* a stream of byte code
|
|
||||||
* @param constantPool
|
|
||||||
* the constant pool of the the current class
|
|
||||||
* @throws WasmException
|
|
||||||
* if some Java code can't converted
|
|
||||||
*/
|
|
||||||
private void prepareCodeChunk( CodeInputStream byteCode, ConstantPool constantPool ) throws WasmException {
|
|
||||||
try {
|
|
||||||
while( byteCode.available() > 0 ) {
|
|
||||||
int codePosition = byteCode.getCodePosition();
|
|
||||||
int op = byteCode.readUnsignedByte();
|
|
||||||
switch( op ) {
|
|
||||||
case 2: // iconst_m1
|
|
||||||
case 3: // iconst_0
|
|
||||||
case 4: // iconst_1
|
|
||||||
case 5: // iconst_2
|
|
||||||
case 6: // iconst_3
|
|
||||||
case 7: // iconst_4
|
|
||||||
case 8: // iconst_5
|
|
||||||
stackManager.add( ValueType.i32, codePosition );
|
|
||||||
break;
|
|
||||||
case 9: // lconst_0
|
|
||||||
case 10: // lconst_1
|
|
||||||
stackManager.add( ValueType.i64, codePosition );
|
|
||||||
break;
|
|
||||||
case 11: // fconst_0
|
|
||||||
case 12: // fconst_1
|
|
||||||
case 13: // fconst_2
|
|
||||||
stackManager.add( ValueType.f32, codePosition );
|
|
||||||
break;
|
|
||||||
case 14: // dconst_0
|
|
||||||
case 15: // dconst_1
|
|
||||||
stackManager.add( ValueType.f64, codePosition );
|
|
||||||
break;
|
|
||||||
case 16: // bipush
|
|
||||||
stackManager.add( ValueType.i32, codePosition );
|
|
||||||
byteCode.skip(1);
|
|
||||||
break;
|
|
||||||
case 17: // sipush
|
|
||||||
stackManager.add( ValueType.i32, codePosition );
|
|
||||||
byteCode.skip(2);
|
|
||||||
break;
|
|
||||||
case 18: // ldc
|
|
||||||
stackManager.add( null, codePosition );
|
|
||||||
byteCode.skip(1);
|
|
||||||
break;
|
|
||||||
case 19: // ldc_w
|
|
||||||
case 20: // ldc2_w
|
|
||||||
stackManager.add( null, codePosition );
|
|
||||||
byteCode.skip(2);
|
|
||||||
break;
|
|
||||||
case 21: // iload
|
|
||||||
stackManager.add( ValueType.i32, codePosition );
|
|
||||||
localVariables.use( ValueType.i32, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 22: // lload
|
|
||||||
stackManager.add( ValueType.i64, codePosition );
|
|
||||||
localVariables.use( ValueType.i64, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 23: // fload
|
|
||||||
stackManager.add( ValueType.f32, codePosition );
|
|
||||||
localVariables.use( ValueType.f32, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 24: // dload
|
|
||||||
stackManager.add( ValueType.f64, codePosition );
|
|
||||||
localVariables.use( ValueType.f64, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 26: // iload_0
|
|
||||||
case 27: // iload_1
|
|
||||||
case 28: // iload_2
|
|
||||||
case 29: // iload_3
|
|
||||||
stackManager.add( ValueType.i32, codePosition );
|
|
||||||
localVariables.use( ValueType.i32, op - 26 );
|
|
||||||
break;
|
|
||||||
case 30: // lload_0
|
|
||||||
case 31: // lload_1
|
|
||||||
case 32: // lload_2
|
|
||||||
case 33: // lload_3
|
|
||||||
stackManager.add( ValueType.i64, codePosition );
|
|
||||||
localVariables.use( ValueType.i64, op - 30 );
|
|
||||||
break;
|
|
||||||
case 34: // fload_0
|
|
||||||
case 35: // fload_1
|
|
||||||
case 36: // fload_2
|
|
||||||
case 37: // fload_3
|
|
||||||
stackManager.add( ValueType.f32, codePosition );
|
|
||||||
localVariables.use( ValueType.f32, op - 34 );
|
|
||||||
break;
|
|
||||||
case 38: // dload_0
|
|
||||||
case 39: // dload_1
|
|
||||||
case 40: // dload_2
|
|
||||||
case 41: // dload_3
|
|
||||||
stackManager.add( ValueType.f64, codePosition );
|
|
||||||
localVariables.use( ValueType.f64, op - 38 );
|
|
||||||
break;
|
|
||||||
case 54: // istore
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.i32, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 55: // lstore
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.i64, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 56: // fstore
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.f32, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 57: // dstore
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.f64, byteCode.readUnsignedByte() );
|
|
||||||
break;
|
|
||||||
case 59: // istore_0
|
|
||||||
case 60: // istore_1
|
|
||||||
case 61: // istore_2
|
|
||||||
case 62: // istore_3
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.i32, op - 59 );
|
|
||||||
break;
|
|
||||||
case 63: // lstore_0
|
|
||||||
case 64: // lstore_1
|
|
||||||
case 65: // lstore_2
|
|
||||||
case 66: // lstore_3
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.i64, op - 63 );
|
|
||||||
break;
|
|
||||||
case 67: // fstore_0
|
|
||||||
case 68: // fstore_1
|
|
||||||
case 69: // fstore_2
|
|
||||||
case 70: // fstore_3
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.f32, op - 67 );
|
|
||||||
break;
|
|
||||||
case 71: // dstore_0
|
|
||||||
case 72: // dstore_1
|
|
||||||
case 73: // dstore_2
|
|
||||||
case 74: // dstore_3
|
|
||||||
stackManager.remove();
|
|
||||||
localVariables.use( ValueType.f64, op - 71 );
|
|
||||||
break;
|
|
||||||
case 87: // pop
|
|
||||||
case 88: // pop2
|
|
||||||
stackManager.remove();
|
|
||||||
break;
|
|
||||||
case 25: //aload
|
|
||||||
case 58: // astore
|
|
||||||
case 179: // putstatic
|
|
||||||
case 181: // putfield
|
|
||||||
byteCode.skip(1);
|
|
||||||
break;
|
|
||||||
case 132: // iinc
|
|
||||||
byteCode.skip( 2);
|
|
||||||
break;
|
|
||||||
case 153: // ifeq
|
|
||||||
case 154: // ifne
|
|
||||||
case 155: // iflt
|
|
||||||
case 156: // ifge
|
|
||||||
case 157: // ifgt
|
|
||||||
case 158: // ifle
|
|
||||||
case 159: // if_icmpeq
|
|
||||||
case 160: // if_icmpne
|
|
||||||
case 161: // if_icmplt
|
|
||||||
case 162: // if_icmpge
|
|
||||||
case 163: // if_icmpgt
|
|
||||||
case 164: // if_icmple
|
|
||||||
case 165: // if_acmpeq
|
|
||||||
case 166: // if_acmpne
|
|
||||||
int offset = byteCode.readShort();
|
|
||||||
branchManager.start( JavaBlockOperator.IF, codePosition, offset, byteCode.getLineNumber() );
|
|
||||||
break;
|
|
||||||
case 167: // goto
|
|
||||||
offset = byteCode.readShort();
|
|
||||||
branchManager.start( JavaBlockOperator.GOTO, codePosition, offset, byteCode.getLineNumber() );
|
|
||||||
break;
|
|
||||||
case 170: // tableswitch
|
|
||||||
case 171: // lookupswitch
|
|
||||||
prepareSwitchCode( byteCode, op == 171, byteCode.getLineNumber() );
|
|
||||||
break;
|
|
||||||
case 184: // invokestatic
|
|
||||||
ConstantRef method = (ConstantRef)constantPool.get( byteCode.readUnsignedShort() );
|
|
||||||
String signature = method.getType();
|
|
||||||
ValueType type = getValueType( signature, signature.indexOf( ')' ) + 1 );
|
|
||||||
if( type != null ) {
|
|
||||||
stackManager.add( type, codePosition );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
throw WasmException.create( ex, sourceFile, byteCode.getLineNumber() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the both switch operation codes.
|
|
||||||
*
|
|
||||||
* @param byteCode
|
|
||||||
* the current stream with a position after the operation code
|
|
||||||
* @param isLookupSwitch
|
|
||||||
* true, if the operation was a loopupswitch; false, if the operation was a tableswitch
|
|
||||||
* @param lineNumber
|
|
||||||
* the current line number
|
|
||||||
* @throws IOException
|
|
||||||
* if any I/O error occur
|
|
||||||
*/
|
|
||||||
private void prepareSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch, int lineNumber ) throws IOException {
|
|
||||||
int startPosition = byteCode.getCodePosition();
|
|
||||||
int padding = startPosition % 4;
|
|
||||||
if( padding > 0 ) {
|
|
||||||
byteCode.skip( 4 - padding );
|
|
||||||
}
|
|
||||||
startPosition--;
|
|
||||||
|
|
||||||
int defaultPosition = startPosition + byteCode.readInt();
|
|
||||||
int[] keys;
|
|
||||||
int[] positions;
|
|
||||||
if( isLookupSwitch ) { // lookupswitch
|
|
||||||
localVariables.useTempI32();
|
|
||||||
int nPairs = byteCode.readInt();
|
|
||||||
keys = new int[nPairs];
|
|
||||||
positions = new int[nPairs];
|
|
||||||
for( int i = 0; i < nPairs; i++ ) {
|
|
||||||
keys[i] = byteCode.readInt();
|
|
||||||
positions[i] = startPosition + byteCode.readInt();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int low = byteCode.readInt();
|
|
||||||
keys = null;
|
|
||||||
int count = byteCode.readInt() - low + 1;
|
|
||||||
positions = new int[count];
|
|
||||||
for( int i = 0; i < count; i++ ) {
|
|
||||||
positions[i] = startPosition + byteCode.readInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int switchValuestartPosition = stackManager.getCodePosition( 0 );
|
|
||||||
branchManager.startSwitch( switchValuestartPosition, 0, lineNumber, keys, positions, defaultPosition );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the byte code of a method.
|
* Write the byte code of a method.
|
||||||
*
|
*
|
||||||
@ -543,110 +300,119 @@ public class ModuleGenerator {
|
|||||||
case 6: // iconst_3
|
case 6: // iconst_3
|
||||||
case 7: // iconst_4
|
case 7: // iconst_4
|
||||||
case 8: // iconst_5
|
case 8: // iconst_5
|
||||||
|
stackManager.add( ValueType.i32, codePos );
|
||||||
instr = new WasmConstInstruction( Integer.valueOf( op - 3 ), codePos );
|
instr = new WasmConstInstruction( Integer.valueOf( op - 3 ), codePos );
|
||||||
break;
|
break;
|
||||||
case 9: // lconst_0
|
case 9: // lconst_0
|
||||||
case 10: // lconst_1
|
case 10: // lconst_1
|
||||||
|
stackManager.add( ValueType.i64, codePos );
|
||||||
instr = new WasmConstInstruction( Long.valueOf( op - 9 ), codePos );
|
instr = new WasmConstInstruction( Long.valueOf( op - 9 ), codePos );
|
||||||
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
|
||||||
|
stackManager.add( ValueType.f32, codePos );
|
||||||
instr = new WasmConstInstruction( Float.valueOf( op - 11 ), codePos );
|
instr = new WasmConstInstruction( Float.valueOf( op - 11 ), codePos );
|
||||||
break;
|
break;
|
||||||
case 14: // dconst_0
|
case 14: // dconst_0
|
||||||
case 15: // dconst_1
|
case 15: // dconst_1
|
||||||
|
stackManager.add( ValueType.f64, codePos );
|
||||||
instr = new WasmConstInstruction( Double.valueOf( op - 14 ), codePos );
|
instr = new WasmConstInstruction( Double.valueOf( op - 14 ), codePos );
|
||||||
break;
|
break;
|
||||||
case 16: // bipush
|
case 16: // bipush
|
||||||
|
stackManager.add( ValueType.i32, codePos );
|
||||||
instr = new WasmConstInstruction( Integer.valueOf( byteCode.readByte() ), codePos );
|
instr = new WasmConstInstruction( Integer.valueOf( byteCode.readByte() ), codePos );
|
||||||
break;
|
break;
|
||||||
case 17: // sipush
|
case 17: // sipush
|
||||||
|
stackManager.add( ValueType.i32, codePos );
|
||||||
instr = new WasmConstInstruction( Integer.valueOf( byteCode.readShort() ), codePos );
|
instr = new WasmConstInstruction( Integer.valueOf( byteCode.readShort() ), codePos );
|
||||||
break;
|
break;
|
||||||
case 18: // ldc
|
case 18: // ldc
|
||||||
|
stackManager.add( null, codePos );
|
||||||
instr = new WasmConstInstruction( (Number)constantPool.get( byteCode.readUnsignedByte() ), codePos );
|
instr = new WasmConstInstruction( (Number)constantPool.get( byteCode.readUnsignedByte() ), codePos );
|
||||||
break;
|
break;
|
||||||
case 19: // ldc_w
|
case 19: // ldc_w
|
||||||
case 20: // ldc2_w
|
case 20: // ldc2_w
|
||||||
|
stackManager.add( null, codePos );
|
||||||
instr = new WasmConstInstruction( (Number)constantPool.get( byteCode.readUnsignedShort() ), codePos );
|
instr = new WasmConstInstruction( (Number)constantPool.get( byteCode.readUnsignedShort() ), codePos );
|
||||||
break;
|
break;
|
||||||
case 21: // iload
|
case 21: // iload
|
||||||
instr = new WasmLoadStoreInstruction( true, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.i32, true, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
case 22: // lload
|
case 22: // lload
|
||||||
instr = new WasmLoadStoreInstruction( true, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.i64, true, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
case 23: // fload
|
case 23: // fload
|
||||||
instr = new WasmLoadStoreInstruction( true, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.f32, true, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
case 24: // dload
|
case 24: // dload
|
||||||
instr = new WasmLoadStoreInstruction( true, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.f64, true, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
//TODO case 25: // aload
|
//TODO case 25: // aload
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( true, op - 26, localVariables, codePos );
|
instr = loadStore( ValueType.i32, true, op - 26, codePos );
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( true, op - 30, localVariables, codePos );
|
instr = loadStore( ValueType.i64, true, op - 30, codePos );
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( true, op - 34, localVariables, codePos );
|
instr = loadStore( ValueType.f32, true, op - 34, codePos );
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( true, op - 38, localVariables, codePos );
|
instr = loadStore( ValueType.f64, true, op - 38, codePos );
|
||||||
break;
|
break;
|
||||||
case 54: // istore
|
case 54: // istore
|
||||||
instr = new WasmLoadStoreInstruction( false, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.i32, false, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
case 55: // lstore
|
case 55: // lstore
|
||||||
instr = new WasmLoadStoreInstruction( false, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.i64, false, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
case 56: // fstore
|
case 56: // fstore
|
||||||
instr = new WasmLoadStoreInstruction( false, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.f32, false, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
case 57: // dstore
|
case 57: // dstore
|
||||||
instr = new WasmLoadStoreInstruction( false, byteCode.readUnsignedByte(), localVariables, codePos );
|
instr = loadStore( ValueType.f64, false, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
//TODO case 58: // astore
|
//TODO case 58: // astore
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( false, op - 59, localVariables, codePos );
|
instr = loadStore( ValueType.i32, false, op - 59, codePos );
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( false, op - 63, localVariables, codePos );
|
instr = loadStore( ValueType.i64, false, op - 63, codePos );
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( false, op - 67, localVariables, codePos );
|
instr = loadStore( ValueType.f32, false, op - 67, codePos );
|
||||||
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
|
||||||
instr = new WasmLoadStoreInstruction( false, op - 71, localVariables, codePos );
|
instr = loadStore( ValueType.f64, false, op - 71, codePos );
|
||||||
break;
|
break;
|
||||||
case 87: // pop
|
case 87: // pop
|
||||||
case 88: // pop2
|
case 88: // pop2
|
||||||
|
stackManager.remove();
|
||||||
instr = new WasmBlockInstruction( WasmBlockOperator.DROP, null, codePos );
|
instr = new WasmBlockInstruction( WasmBlockOperator.DROP, null, codePos );
|
||||||
break;
|
break;
|
||||||
case 89: // dup: duplicate the value on top of the stack
|
case 89: // dup: duplicate the value on top of the stack
|
||||||
@ -878,8 +644,9 @@ public class ModuleGenerator {
|
|||||||
//TODO case 165: // if_acmpeq
|
//TODO case 165: // if_acmpeq
|
||||||
//TODO case 166: // if_acmpne
|
//TODO case 166: // if_acmpne
|
||||||
case 167: // goto
|
case 167: // goto
|
||||||
|
int offset = byteCode.readShort();
|
||||||
|
branchManager.start( JavaBlockOperator.GOTO, codePos, offset, byteCode.getLineNumber() );
|
||||||
instr = new WasmNopInstruction( codePos ); // marker of the line number for the branch manager
|
instr = new WasmNopInstruction( codePos ); // marker of the line number for the branch manager
|
||||||
byteCode.skip(2); // handle in the branch manager
|
|
||||||
break;
|
break;
|
||||||
case 170: // tableswitch
|
case 170: // tableswitch
|
||||||
case 171: // lookupswitch
|
case 171: // lookupswitch
|
||||||
@ -896,6 +663,11 @@ public class ModuleGenerator {
|
|||||||
case 184: // invokestatic
|
case 184: // invokestatic
|
||||||
idx = byteCode.readUnsignedShort();
|
idx = byteCode.readUnsignedShort();
|
||||||
ConstantRef method = (ConstantRef)constantPool.get( idx );
|
ConstantRef method = (ConstantRef)constantPool.get( idx );
|
||||||
|
String signature = method.getType();
|
||||||
|
ValueType type = getValueType( signature, signature.indexOf( ')' ) + 1 );
|
||||||
|
if( type != null ) {
|
||||||
|
stackManager.add( type, codePos );
|
||||||
|
}
|
||||||
instr = new WasmCallInstruction( method.getConstantClass().getName() + '.' + method.getName() + method.getType(), codePos );
|
instr = new WasmCallInstruction( method.getConstantClass().getName() + '.' + method.getName() + method.getType(), codePos );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -905,6 +677,7 @@ public class ModuleGenerator {
|
|||||||
instructions.add( instr );
|
instructions.add( instr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
branchManager.calculate();
|
||||||
branchManager.handle( byteCode ); // add branch operations
|
branchManager.handle( byteCode ); // add branch operations
|
||||||
if( !endWithReturn && returnType != null ) {
|
if( !endWithReturn && returnType != null ) {
|
||||||
// if a method ends with a loop without a break then code after the loop is no reachable
|
// if a method ends with a loop without a break then code after the loop is no reachable
|
||||||
@ -930,6 +703,7 @@ public class ModuleGenerator {
|
|||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) throws IOException {
|
private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch ) throws IOException {
|
||||||
|
int lineNumber = byteCode.getLineNumber();
|
||||||
int codePos = byteCode.getCodePosition();
|
int codePos = byteCode.getCodePosition();
|
||||||
int startPosition = codePos;
|
int startPosition = codePos;
|
||||||
int padding = startPosition % 4;
|
int padding = startPosition % 4;
|
||||||
@ -938,14 +712,17 @@ public class ModuleGenerator {
|
|||||||
}
|
}
|
||||||
startPosition--;
|
startPosition--;
|
||||||
|
|
||||||
int defaultPosition = byteCode.readInt();
|
int defaultPosition = startPosition + byteCode.readInt();
|
||||||
|
int[] keys;
|
||||||
|
int[] positions;
|
||||||
if( isLookupSwitch ) { // lookupswitch
|
if( isLookupSwitch ) { // lookupswitch
|
||||||
|
localVariables.useTempI32();
|
||||||
int count = byteCode.readInt();
|
int count = byteCode.readInt();
|
||||||
int[] keys = new int[count];
|
keys = new int[count];
|
||||||
int[] positions = new int[count];
|
positions = new int[count];
|
||||||
for( int i = 0; i < count; i++ ) {
|
for( int i = 0; i < count; i++ ) {
|
||||||
keys[i] = byteCode.readInt();
|
keys[i] = byteCode.readInt();
|
||||||
positions[i] = byteCode.readInt();
|
positions[i] = startPosition + byteCode.readInt();
|
||||||
}
|
}
|
||||||
int tempI32 = localVariables.getTempI32();
|
int tempI32 = localVariables.getTempI32();
|
||||||
int block = 0;
|
int block = 0;
|
||||||
@ -982,15 +759,19 @@ public class ModuleGenerator {
|
|||||||
instructions.add( new WasmBlockInstruction( WasmBlockOperator.BR, defaultBlock, codePos ) );
|
instructions.add( new WasmBlockInstruction( WasmBlockOperator.BR, defaultBlock, codePos ) );
|
||||||
} else {
|
} else {
|
||||||
int low = byteCode.readInt();
|
int low = byteCode.readInt();
|
||||||
|
keys = null;
|
||||||
int count = byteCode.readInt() - low + 1;
|
int count = byteCode.readInt() - low + 1;
|
||||||
|
positions = new int[count];
|
||||||
for( int i = 0; i < count; i++ ) {
|
for( int i = 0; i < count; i++ ) {
|
||||||
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
|
||||||
instructions.add( new WasmConstInstruction( low, codePos ) );
|
instructions.add( new WasmConstInstruction( low, codePos ) );
|
||||||
instructions.add( new WasmNumericInstruction( NumericOperator.sub, ValueType.i32, codePos ) );
|
instructions.add( new WasmNumericInstruction( NumericOperator.sub, ValueType.i32, codePos ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int switchValuestartPosition = stackManager.getCodePosition( 0 );
|
||||||
|
branchManager.startSwitch( switchValuestartPosition, 0, lineNumber, keys, positions, defaultPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1014,6 +795,26 @@ public class ModuleGenerator {
|
|||||||
return find ? next : current;
|
return find ? next : current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a WasmLoadStoreInstruction.
|
||||||
|
*
|
||||||
|
* @param valueType
|
||||||
|
* the value type
|
||||||
|
* @param load
|
||||||
|
* true: if load
|
||||||
|
* @param idx
|
||||||
|
* the memory/slot idx of the variable
|
||||||
|
* @param codePos
|
||||||
|
* the code position/offset in the Java method
|
||||||
|
* @return the WasmLoadStoreInstruction
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
private WasmLoadStoreInstruction loadStore( ValueType valueType, boolean load, @Nonnegative int idx, int codePos ) {
|
||||||
|
stackManager.add( valueType, codePos );
|
||||||
|
localVariables.use( valueType, idx );
|
||||||
|
return new WasmLoadStoreInstruction( load, idx, localVariables, codePos );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@ -1053,6 +854,7 @@ public class ModuleGenerator {
|
|||||||
*/
|
*/
|
||||||
private void opIfCompareCondition( NumericOperator ifNumOp, NumericOperator continueNumOp, CodeInputStream byteCode, int codePos ) throws IOException {
|
private void opIfCompareCondition( NumericOperator ifNumOp, NumericOperator continueNumOp, CodeInputStream byteCode, int codePos ) throws IOException {
|
||||||
int offset = byteCode.readShort();
|
int offset = byteCode.readShort();
|
||||||
|
branchManager.start( JavaBlockOperator.IF, codePos, offset, byteCode.getLineNumber() );
|
||||||
instructions.add( new WasmNumericInstruction( offset > 0 ? ifNumOp : continueNumOp, ValueType.i32, codePos ) );
|
instructions.add( new WasmNumericInstruction( offset > 0 ? ifNumOp : continueNumOp, ValueType.i32, codePos ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,6 +872,7 @@ public class ModuleGenerator {
|
|||||||
* 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 ) throws IOException {
|
||||||
|
codePos = byteCode.getCodePosition();
|
||||||
NumericOperator numOp;
|
NumericOperator numOp;
|
||||||
int nextOp = byteCode.read();
|
int nextOp = byteCode.read();
|
||||||
switch( nextOp ){
|
switch( nextOp ){
|
||||||
@ -1094,7 +897,8 @@ public class ModuleGenerator {
|
|||||||
default:
|
default:
|
||||||
throw new WasmException( "Unexpected compare sub operation: " + nextOp, null, -1 );
|
throw new WasmException( "Unexpected compare sub operation: " + nextOp, null, -1 );
|
||||||
}
|
}
|
||||||
byteCode.skip(2);
|
int offset = byteCode.readShort();
|
||||||
|
branchManager.start( JavaBlockOperator.IF, codePos, offset, byteCode.getLineNumber() );
|
||||||
instructions.add( new WasmNumericInstruction( numOp, valueType, codePos ) );
|
instructions.add( new WasmNumericInstruction( numOp, valueType, codePos ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user