improve exception message

This commit is contained in:
Volker Berlin 2018-10-13 21:51:34 +02:00
parent c3b04e7016
commit ce3e2d7546
7 changed files with 44 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2017 Volker Berlin (i-net software) * Copyright 2017 - 2018 Volker Berlin (i-net software)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,6 +27,8 @@ public class WasmException extends RuntimeException {
private String sourceFile; private String sourceFile;
private String className;
/** /**
* Create a new instance. * Create a new instance.
* *
@ -34,10 +36,12 @@ public class WasmException extends RuntimeException {
* the error message * the error message
* @param sourceFile * @param sourceFile
* the sourceFile of the Java code * the sourceFile of the Java code
* @param className
* the class name of the Java code
* @param lineNumber * @param lineNumber
* the line number in Java Code * the line number in Java Code
*/ */
public WasmException( String message, String sourceFile, int lineNumber ) { public WasmException( String message, String sourceFile, String className, int lineNumber ) {
super( message ); super( message );
this.sourceFile = sourceFile; this.sourceFile = sourceFile;
this.lineNumber = lineNumber; this.lineNumber = lineNumber;
@ -60,16 +64,21 @@ public class WasmException extends RuntimeException {
* @param cause * @param cause
* the wrapped cause * the wrapped cause
* @param sourceFile * @param sourceFile
* the sourceFile of the Java code * the source file of the Java code
* @param className
* the class name of the Java code
* @param lineNumber * @param lineNumber
* the line number in Java Code * the line number in Java Code
* @return a new instance * @return a new instance
*/ */
public static WasmException create( Throwable cause, String sourceFile, int lineNumber ) { public static WasmException create( Throwable cause, String sourceFile, String className, int lineNumber ) {
WasmException wasmEx = create( cause ); WasmException wasmEx = create( cause );
if( wasmEx.sourceFile == null ) { if( wasmEx.sourceFile == null ) {
wasmEx.sourceFile = sourceFile; wasmEx.sourceFile = sourceFile;
} }
if( wasmEx.className == null ) {
wasmEx.className = className;
}
if( wasmEx.lineNumber < 0 ) { if( wasmEx.lineNumber < 0 ) {
wasmEx.lineNumber = lineNumber; wasmEx.lineNumber = lineNumber;
} }
@ -103,13 +112,19 @@ public class WasmException extends RuntimeException {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public String toString() { public String getMessage() {
String str = super.toString(); String str = super.getMessage();
if( sourceFile != null || lineNumber > 0 ) { if( sourceFile != null || className != null || lineNumber >= 0 ) {
str += " at " + (sourceFile != null ? sourceFile : "line"); str += "\n\tat ";
if( className != null ) {
str += className.replace( '/', '.' ).replace( '$', '.' );
}
str += "(";
str += (sourceFile != null ? sourceFile : "line");
if( lineNumber > 0 ) { if( lineNumber > 0 ) {
str += ":" + lineNumber; str += ":" + lineNumber;
} }
str += ")";
} }
return str; return str;
} }

View File

@ -693,7 +693,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
if( entry != null ) { if( entry != null ) {
id = entry.id; id = entry.id;
} else { } else {
throw new WasmException( "Call to unknown function: " + name, null, -1 ); throw new WasmException( "Call to unknown function: " + name, null, null, -1 );
} }
} }
codeStream.writeOpCode( CALL ); codeStream.writeOpCode( CALL );

View File

@ -142,7 +142,7 @@ class BranchManger {
loop.endPosition = parsedBlock.startPosition + 3; loop.endPosition = parsedBlock.startPosition + 3;
break; break;
default: default:
throw new WasmException( "Unimplemented loop code operation: " + parsedBlock.op, null, parsedBlock.lineNumber ); throw new WasmException( "Unimplemented loop code operation: " + parsedBlock.op, null, null, parsedBlock.lineNumber );
} }
} else { } else {
switch ( parsedBlock.op ) { switch ( parsedBlock.op ) {
@ -225,7 +225,7 @@ class BranchManger {
calculateLoop( parent, parsedBlock, parsedOperations ); calculateLoop( parent, parsedBlock, parsedOperations );
break; break;
default: default:
throw new WasmException( "Unimplemented block code operation: " + parsedBlock.op, null, parsedBlock.lineNumber ); throw new WasmException( "Unimplemented block code operation: " + parsedBlock.op, null, null, parsedBlock.lineNumber );
} }
} }
} }
@ -538,7 +538,7 @@ class BranchManger {
deep++; deep++;
} }
} }
throw new WasmException( "GOTO code without target loop/block", null, gotoBlock.lineNumber ); throw new WasmException( "GOTO code without target loop/block", null, null, gotoBlock.lineNumber );
} }
@ -658,7 +658,7 @@ class BranchManger {
newOp = NumericOperator.lt; newOp = NumericOperator.lt;
break; break;
default: default:
throw new WasmException( "Not a compare operation: " + instr.numOp, null, lineNumber ); throw new WasmException( "Not a compare operation: " + instr.numOp, null, null, lineNumber );
} }
instr.numOp = newOp; instr.numOp = newOp;
} }

View File

@ -78,7 +78,7 @@ class LocaleVariableManager {
LocaleVariable var = variables[slot]; LocaleVariable var = variables[slot];
if( var.valueType != null && var.valueType != valueType ) { if( var.valueType != null && var.valueType != valueType ) {
throw new WasmException( "Redefine local variable type from " + var.valueType + " to " throw new WasmException( "Redefine local variable type from " + var.valueType + " to "
+ valueType, null, -1 ); + valueType, null, null, -1 );
} }
var.valueType = valueType; var.valueType = valueType;
} }

View File

@ -48,6 +48,8 @@ public class ModuleGenerator {
private String sourceFile; private String sourceFile;
private String className;
private final List<WasmInstruction> instructions = new ArrayList<>(); private final List<WasmInstruction> instructions = new ArrayList<>();
private BranchManger branchManager = new BranchManger( instructions ); private BranchManger branchManager = new BranchManger( instructions );
@ -96,11 +98,10 @@ public class ModuleGenerator {
private void iterateMethods( ClassFile classFile, Consumer<MethodInfo> handler ) throws WasmException { private void iterateMethods( ClassFile classFile, Consumer<MethodInfo> handler ) throws WasmException {
sourceFile = null; // clear previous value for the case an IO exception occur sourceFile = null; // clear previous value for the case an IO exception occur
className = null;
try { try {
sourceFile = classFile.getSourceFile(); sourceFile = classFile.getSourceFile();
if( sourceFile == null ) { className = classFile.getThisClass().getName();
sourceFile = classFile.getThisClass().getName();
}
MethodInfo[] methods = classFile.getMethods(); MethodInfo[] methods = classFile.getMethods();
for( MethodInfo method : methods ) { for( MethodInfo method : methods ) {
Code code = method.getCode(); Code code = method.getCode();
@ -111,7 +112,7 @@ public class ModuleGenerator {
handler.accept( method ); handler.accept( method );
} }
} catch( IOException ioex ) { } catch( IOException ioex ) {
throw WasmException.create( ioex, sourceFile, -1 ); throw WasmException.create( ioex, sourceFile, className, -1 );
} }
} }
@ -136,7 +137,7 @@ public class ModuleGenerator {
writer.prepareFunction( name ); writer.prepareFunction( name );
} }
} catch( Exception ioex ) { } catch( Exception ioex ) {
throw WasmException.create( ioex, sourceFile, -1 ); throw WasmException.create( ioex, sourceFile, className, -1 );
} }
} }
@ -172,7 +173,7 @@ public class ModuleGenerator {
} }
} catch( Exception ioex ) { } catch( Exception ioex ) {
int lineNumber = byteCode == null ? -1 : byteCode.getLineNumber(); int lineNumber = byteCode == null ? -1 : byteCode.getLineNumber();
throw WasmException.create( ioex, sourceFile, lineNumber ); throw WasmException.create( ioex, sourceFile, className, lineNumber );
} }
} }
@ -411,7 +412,7 @@ public class ModuleGenerator {
case 94: // dup2_x2 case 94: // dup2_x2
case 95: // swap case 95: // swap
// can be do with functions with more as one return value in future WASM standard // can be do with functions with more as one return value in future WASM standard
throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: " + op, sourceFile, byteCode.getLineNumber() ); throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: " + op, sourceFile, className, byteCode.getLineNumber() );
case 96: // iadd case 96: // iadd
instr = new WasmNumericInstruction( NumericOperator.add, ValueType.i32, codePos); instr = new WasmNumericInstruction( NumericOperator.add, ValueType.i32, codePos);
break; break;
@ -469,7 +470,7 @@ public class ModuleGenerator {
case 114: // frem case 114: // frem
case 115: // drem case 115: // drem
//TODO can be implemented with a helper function like: (a - (long)(a / b) * (double)b) //TODO can be implemented with a helper function like: (a - (long)(a / b) * (double)b)
throw new WasmException( "Modulo/Remainder for floating numbers is not supported in WASM. Use int or long data types." + op, sourceFile, byteCode.getLineNumber() ); throw new WasmException( "Modulo/Remainder for floating numbers is not supported in WASM. Use int or long data types." + op, sourceFile, className, byteCode.getLineNumber() );
case 116: // ineg case 116: // ineg
instructions.add( new WasmConstInstruction( -1, ValueType.i32, codePos ) ); instructions.add( new WasmConstInstruction( -1, ValueType.i32, codePos ) );
instr = new WasmNumericInstruction( NumericOperator.mul, ValueType.i32, codePos ); instr = new WasmNumericInstruction( NumericOperator.mul, ValueType.i32, codePos );
@ -698,7 +699,7 @@ public class ModuleGenerator {
//TODO case 200: // goto_w //TODO case 200: // goto_w
//TODO case 201: // jsr_w //TODO case 201: // jsr_w
default: default:
throw new WasmException( "Unimplemented Java byte code operation: " + op, sourceFile, byteCode.getLineNumber() ); throw new WasmException( "Unimplemented Java byte code operation: " + op, sourceFile, className, byteCode.getLineNumber() );
} }
if( instr != null ) { if( instr != null ) {
instructions.add( instr ); instructions.add( instr );
@ -715,7 +716,7 @@ public class ModuleGenerator {
} catch( WasmException ex ) { } catch( WasmException ex ) {
throw ex; throw ex;
} catch( Exception ex ) { } catch( Exception ex ) {
throw WasmException.create( ex, sourceFile, byteCode.getLineNumber() ); throw WasmException.create( ex, sourceFile, className, byteCode.getLineNumber() );
} }
} }
@ -819,7 +820,7 @@ public class ModuleGenerator {
return instr.getCodePosition(); return instr.getCodePosition();
} }
} }
throw new WasmException( "Switch start position not found", sourceFile, -1 ); // should never occur throw new WasmException( "Switch start position not found", sourceFile, className, -1 ); // should never occur
} }
/** /**
@ -939,7 +940,7 @@ public class ModuleGenerator {
numOp = NumericOperator.le; numOp = NumericOperator.le;
break; break;
default: default:
throw new WasmException( "Unexpected compare sub operation: " + nextOp, null, -1 ); throw new WasmException( "Unexpected compare sub operation: " + nextOp, sourceFile, className, -1 );
} }
int offset = byteCode.readShort(); int offset = byteCode.readShort();
WasmNumericInstruction compare = new WasmNumericInstruction( numOp, valueType, codePos ); WasmNumericInstruction compare = new WasmNumericInstruction( numOp, valueType, codePos );

View File

@ -87,7 +87,7 @@ public enum ValueType {
default: default:
javaType = javaSignature.substring( idx, idx + 1 ); javaType = javaSignature.substring( idx, idx + 1 );
} }
throw new WasmException( "Not supported Java data type in method signature: " + javaType, null, -1 ); throw new WasmException( "Not supported Java data type in method signature: " + javaType, null, null, -1 );
} }
} }

View File

@ -81,7 +81,7 @@ class WasmConstInstruction extends WasmInstruction {
} else if( clazz == Double.class ) { } else if( clazz == Double.class ) {
return ValueType.f64; return ValueType.f64;
} else { } else {
throw new WasmException( "Not supported constant type: " + clazz, null, -1 ); throw new WasmException( "Not supported constant type: " + clazz, null, null, -1 );
} }
} }