write extra parameter for instance methods (non static)

This commit is contained in:
Volker Berlin 2018-12-13 22:32:51 +01:00
parent d4012a751f
commit 7701ce6993
2 changed files with 52 additions and 8 deletions

View File

@ -171,14 +171,20 @@ public class ModuleGenerator {
FunctionName name = new FunctionName( method ); FunctionName name = new FunctionName( method );
Map<String,Object> annotationValues = method.getAnnotation( JWebAssembly.IMPORT_ANNOTATION ); Map<String,Object> annotationValues = method.getAnnotation( JWebAssembly.IMPORT_ANNOTATION );
if( annotationValues != null ) { if( annotationValues != null ) {
if( !method.isStatic() ) {
throw new WasmException( "Import method must be static: " + name.fullName, -1 );
}
functions.writeFunction( name ); functions.writeFunction( name );
String impoarModule = (String)annotationValues.get( "module" ); String impoarModule = (String)annotationValues.get( "module" );
String importName = (String)annotationValues.get( "name" ); String importName = (String)annotationValues.get( "name" );
writer.prepareImport( name, impoarModule, importName ); writer.prepareImport( name, impoarModule, importName );
writeMethodSignature( name, null, null ); writeMethodSignature( name, true, null, null );
} else { } else {
annotationValues = method.getAnnotation( JWebAssembly.EXPORT_ANNOTATION ); annotationValues = method.getAnnotation( JWebAssembly.EXPORT_ANNOTATION );
if( annotationValues != null ) { if( annotationValues != null ) {
if( !method.isStatic() ) {
throw new WasmException( "Export method must be static: " + name.fullName, -1 );
}
functions.functionCall( name ); functions.functionCall( name );
} }
} }
@ -225,7 +231,7 @@ public class ModuleGenerator {
writer.writeMethodStart( name ); writer.writeMethodStart( name );
functions.writeFunction( name ); functions.writeFunction( name );
LocalVariableTable localVariableTable = code == null ? null : code.getLocalVariableTable(); LocalVariableTable localVariableTable = code == null ? null : code.getLocalVariableTable();
writeMethodSignature( name, localVariableTable, codeBuilder ); writeMethodSignature( name, method.isStatic(), localVariableTable, codeBuilder );
for( WasmInstruction instruction : codeBuilder.getInstructions() ) { for( WasmInstruction instruction : codeBuilder.getInstructions() ) {
if( instruction instanceof WasmCallInstruction ) { if( instruction instanceof WasmCallInstruction ) {
@ -267,6 +273,8 @@ public class ModuleGenerator {
* *
* @param name * @param name
* the Java signature, typical method.getType(); * the Java signature, typical method.getType();
* @param isStatic
* if method is static
* @param variables * @param variables
* Java variable table with names of the variables for debugging * Java variable table with names of the variables for debugging
* @param codeBuilder * @param codeBuilder
@ -276,9 +284,12 @@ public class ModuleGenerator {
* @throws WasmException * @throws WasmException
* if some Java code can't converted * if some Java code can't converted
*/ */
private void writeMethodSignature( FunctionName name, @Nullable LocalVariableTable variables, WasmCodeBuilder codeBuilder ) throws IOException, WasmException { private void writeMethodSignature( FunctionName name, boolean isStatic, @Nullable LocalVariableTable variables, WasmCodeBuilder codeBuilder ) throws IOException, WasmException {
String signature = name.signature; String signature = name.signature;
int paramCount = 0; int paramCount = 0;
if( !isStatic ) {
writer.writeMethodParam( "param", ValueType.anyref, "this" );
}
ValueTypeParser parser = new ValueTypeParser( signature ); ValueTypeParser parser = new ValueTypeParser( signature );
ValueType type; ValueType type;
for( String kind : new String[] {"param","result"}) { for( String kind : new String[] {"param","result"}) {
@ -296,6 +307,9 @@ public class ModuleGenerator {
} }
} }
if( codeBuilder != null ) { if( codeBuilder != null ) {
if( !isStatic ) {
paramCount++;
}
List<ValueType> localTypes = codeBuilder.getLocalTypes( paramCount ); List<ValueType> localTypes = codeBuilder.getLocalTypes( paramCount );
for( int i = 0; i < localTypes.size(); i++ ) { for( int i = 0; i < localTypes.size(); i++ ) {
type = localTypes.get( i ); type = localTypes.get( i );

View File

@ -32,6 +32,7 @@ import de.inetsoftware.jwebassembly.ScriptEngine;
import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.WasmRule; import de.inetsoftware.jwebassembly.WasmRule;
import de.inetsoftware.jwebassembly.api.annotation.Export; import de.inetsoftware.jwebassembly.api.annotation.Export;
import de.inetsoftware.jwebassembly.api.annotation.Import;
/** /**
* @author Volker Berlin * @author Volker Berlin
@ -72,17 +73,21 @@ public class RuntimeErrors {
} }
} }
@Test private void compileErrorTest( String expectedMessge, Class<?> classes ) throws IOException {
public void floatRem() throws IOException { WasmRule wasm = new WasmRule( classes );
WasmRule wasm = new WasmRule( TestModulo.class );
try { try {
wasm.compile(); wasm.compile();
fail( "Floating modulo is not supported" ); fail( "Exception expected with: " + expectedMessge );
} catch( WasmException ex ) { } catch( WasmException ex ) {
assertTrue( ex.toString(), ex.getMessage().contains( "Modulo/Remainder" ) ); assertTrue( "Wrong error message: " + ex.getMessage(), ex.getMessage().contains( expectedMessge ) );
} finally { } finally {
wasm.delete(); wasm.delete();
} }
}
@Test
public void floatRem() throws IOException {
compileErrorTest( "Modulo/Remainder", TestModulo.class );
} }
static class TestModulo { static class TestModulo {
@ -92,4 +97,29 @@ public class RuntimeErrors {
return a % 2F; return a % 2F;
} }
} }
@Test
public void nonStaticExport() throws IOException {
compileErrorTest( "Export method must be static:", NonStaticExport.class );
}
static class NonStaticExport {
@Export
float function() {
return 1;
}
}
@Test
public void nonStaticImport() throws IOException {
compileErrorTest( "Import method must be static:", NonStaticImport.class );
}
static class NonStaticImport {
@Import( module = "m", name = "n" )
float function() {
return 1;
}
}
} }