Instead the static flag we need to handle if there is an additional "this" parameter.

This commit is contained in:
Volker Berlin 2020-01-11 20:31:05 +01:00
parent 396bafa234
commit 1998b2b5b2
7 changed files with 40 additions and 48 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018 - 2019 Volker Berlin (i-net software)
* Copyright 2018 - 2020 Volker Berlin (i-net software)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -104,9 +104,13 @@ public class FunctionManager {
*
* @param name
* the function name
* @param needThisParameter
* if this function need additional to the signature a this parameter
*/
void markAsScanned( FunctionName name ) {
getOrCreate( name ).state = State.Scanned;
void markAsScanned( FunctionName name, boolean needThisParameter ) {
FunctionState state = getOrCreate( name );
state.state = State.Scanned;
state.needThisParameter = needThisParameter;
}
/**
@ -124,11 +128,9 @@ public class FunctionManager {
*
* @param name
* the function name
* @param isStatic
* true, if the method is static
* @return the real function name
*/
FunctionName markAsNeeded( FunctionName name, boolean isStatic ) {
FunctionName markAsNeeded( FunctionName name ) {
FunctionState state = getOrCreate( name );
if( state.state == State.None ) {
if( isFinish ) {
@ -136,7 +138,6 @@ public class FunctionManager {
}
state.state = State.Needed;
}
state.isStatic = isStatic;
return state.alias == null ? name : state.alias;
}
@ -269,8 +270,8 @@ public class FunctionManager {
* the function name
* @return true, if the function is static
*/
boolean isStatic( FunctionName name ) {
return getOrCreate( name ).isStatic;
boolean needThisParameter( FunctionName name ) {
return getOrCreate( name ).needThisParameter;
}
/**
@ -355,7 +356,7 @@ public class FunctionManager {
private int functionIdx = -1;
private boolean isStatic;
private boolean needThisParameter;
}
private static enum State {

View File

@ -195,7 +195,7 @@ public class ModuleGenerator {
} else {
functions.markAsImport( synth, synth.getAnnotation() );
}
functions.markAsScanned( next );
functions.markAsScanned( next, false );
}
} else {
JWebAssembly.LOGGER.fine( "scan class: " + next.className );
@ -205,7 +205,8 @@ public class ModuleGenerator {
if( functions.needToScan( name ) ) {
JWebAssembly.LOGGER.fine( '\t' + name.methodName + name.signature );
scanMethod( createInstructions( functions.replace( name, method ) ) );
functions.markAsScanned( name );
boolean needThisParameter = !method.isStatic() || "<init>".equals( method.getName() );
functions.markAsScanned( name, needThisParameter );
}
} catch (IOException ioex){
throw WasmException.create( ioex, sourceFile, className, -1 );
@ -220,7 +221,7 @@ public class ModuleGenerator {
MethodInfo method = superClassFile.getMethod( next.methodName, next.signature );
if( method != null ) {
FunctionName name = new FunctionName( method );
functions.markAsNeeded( name, method.isStatic() );
functions.markAsNeeded( name );
functions.setAlias( next, name );
continue NEXT; // we have found a super method
}
@ -258,14 +259,14 @@ public class ModuleGenerator {
importName = name.methodName;
}
writer.prepareImport( name, importModule, importName );
writeMethodSignature( name, true, null );
writeMethodSignature( name, null );
javaScript.addImport( importModule, importName, importAnannotation );
}
// init/write the function types
for( Iterator<FunctionName> iterator = functions.getNeededFunctions(); iterator.hasNext(); ) {
FunctionName name = iterator.next();
writeMethodSignature( name, functions.isStatic( name ), null );
writeMethodSignature( name, null );
}
JWebAssembly.LOGGER.fine( "scan finsih" );
@ -292,10 +293,8 @@ public class ModuleGenerator {
for( WasmInstruction instruction : instructions ) {
switch( instruction.getType() ) {
case Call:
((WasmCallInstruction)instruction).markAsNeeded( functions, true );
break;
case CallIndirect:
((WasmCallInstruction)instruction).markAsNeeded( functions, false );
((WasmCallInstruction)instruction).markAsNeeded( functions );
break;
default:
}
@ -314,7 +313,7 @@ public class ModuleGenerator {
className = null;
FunctionName next = it.next();
if( next instanceof SyntheticFunctionName ) {
writeMethodImpl( next, true, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) );
writeMethodImpl( next, ((SyntheticFunctionName)next).getCodeBuilder( watParser ) );
} else {
ClassFile classFile = classFileLoader.get( next.className );
if( classFile == null ) {
@ -393,7 +392,7 @@ public class ModuleGenerator {
}
Map<String,Object> annotationValues;
if( (annotationValues = method.getAnnotation( JWebAssembly.REPLACE_ANNOTATION )) != null ) {
functions.isStatic( name ); // register this class that process the annotation of this replacement function not a second time. iSKnown() returns true now.
functions.needThisParameter( name); // register this class that process the annotation of this replacement function not a second time. iSKnown() returns true now.
String signatureName = (String)annotationValues.get( "value" );
name = new FunctionName( signatureName );
functions.addReplacement( name, method );
@ -409,7 +408,7 @@ public class ModuleGenerator {
if( !method.isStatic() ) {
throw new WasmException( "Export method must be static: " + name.fullName, -1 );
}
functions.markAsNeeded( name, true );
functions.markAsNeeded( name );
return;
}
} catch( Exception ioex ) {
@ -435,7 +434,7 @@ public class ModuleGenerator {
return;
}
writeExport( name, method );
writeMethodImpl( name, functions.isStatic( name ), codeBuilder );
writeMethodImpl( name, codeBuilder );
}
/**
@ -483,8 +482,6 @@ public class ModuleGenerator {
*
* @param name
* the name of the function
* @param isStatic
* if it is static
* @param codeBuilder
* the code builder with instructions
* @throws WasmException
@ -492,10 +489,10 @@ public class ModuleGenerator {
* @throws IOException
* if an i/O error occur
*/
private void writeMethodImpl( FunctionName name, boolean isStatic, WasmCodeBuilder codeBuilder ) throws WasmException, IOException {
private void writeMethodImpl( FunctionName name, WasmCodeBuilder codeBuilder ) throws WasmException, IOException {
writer.writeMethodStart( name, sourceFile );
functions.markAsWritten( name );
writeMethodSignature( name, isStatic, codeBuilder );
writeMethodSignature( name, codeBuilder );
List<WasmInstruction> instructions = codeBuilder.getInstructions();
optimizer.optimze( instructions );
@ -523,10 +520,8 @@ public class ModuleGenerator {
}
break;
case Call:
((WasmCallInstruction)instruction).markAsNeeded( functions, true );
break;
case CallIndirect:
((WasmCallInstruction)instruction).markAsNeeded( functions, false );
((WasmCallInstruction)instruction).markAsNeeded( functions );
break;
case Struct:
if( !writer.options.useGC() ) {
@ -583,8 +578,6 @@ public class ModuleGenerator {
*
* @param name
* the Java signature, typical method.getType();
* @param isStatic
* if method is static
* @param codeBuilder
* the calculated variables
* @throws IOException
@ -592,10 +585,10 @@ public class ModuleGenerator {
* @throws WasmException
* if some Java code can't converted
*/
private void writeMethodSignature( FunctionName name, boolean isStatic, WasmCodeBuilder codeBuilder ) throws IOException, WasmException {
private void writeMethodSignature( FunctionName name, WasmCodeBuilder codeBuilder ) throws IOException, WasmException {
writer.writeMethodParamStart( name );
int paramCount = 0;
if( !isStatic ) {
if( functions.needThisParameter( name ) ) {
StructType instanceType = types.valueOf( name.className );
writer.writeMethodParam( "param", instanceType, "this" );
paramCount++;

View File

@ -1,5 +1,5 @@
/*
Copyright 2019 Volker Berlin (i-net software)
Copyright 2019 - 2020 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -74,7 +74,7 @@ class StringManager extends LinkedHashMap<String, Integer> {
return "i32.const " + stringMemoryOffset;
}
};
functions.markAsNeeded( offsetFunction, true );
functions.markAsNeeded( offsetFunction );
}
return STRING_CONSTANT_FUNCTION;

View File

@ -1,5 +1,5 @@
/*
Copyright 2018 - 2019 Volker Berlin (i-net software)
Copyright 2018 - 2020 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -269,7 +269,7 @@ public class TypeManager {
FunctionName func = methods.get( idx );
if( func.methodName.equals( funcName.methodName ) && func.signature.equals( funcName.signature ) ) {
methods.set( idx, funcName ); // use the override method
functions.markAsNeeded( funcName, false ); // mark all overridden methods also as needed if the super method is used
functions.markAsNeeded( funcName ); // mark all overridden methods also as needed if the super method is used
break;
}
}

View File

@ -1,5 +1,5 @@
/*
Copyright 2019 Volker Berlin (i-net software)
Copyright 2019 - 2020 Volker Berlin (i-net software)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -93,8 +93,8 @@ class WasmCallIndirectInstruction extends WasmCallInstruction {
* {@inheritDoc}
*/
@Override
void markAsNeeded( FunctionManager functions, boolean isStatic ) {
super.markAsNeeded( functions, isStatic );
void markAsNeeded( FunctionManager functions ) {
super.markAsNeeded( functions );
virtualFunctionIdx = functions.getFunctionIndex( getFunctionName() );
}

View File

@ -80,11 +80,9 @@ class WasmCallInstruction extends WasmInstruction {
*
* @param functions
* the function manager
* @param isStatic
* true, if the method is static
*/
void markAsNeeded( @Nonnull FunctionManager functions, boolean isStatic ) {
name = functions.markAsNeeded( name, isStatic && !name.methodName.equals( "<init>" ) ); // a constructor is like static call but has a hidden "this" parameter.
void markAsNeeded( @Nonnull FunctionManager functions ) {
name = functions.markAsNeeded( name );
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2018 - 2019 Volker Berlin (i-net software)
* Copyright 2018 - 2020 Volker Berlin (i-net software)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -391,7 +391,7 @@ public abstract class WasmCodeBuilder {
WasmNumericInstruction numeric = new WasmNumericInstruction( numOp, valueType, javaCodePos, lineNumber );
instructions.add( numeric );
if( !options.useGC() && numOp == NumericOperator.ref_eq ) {
functions.markAsNeeded( options.ref_eq = getNonGC( "ref_eq", lineNumber ), true );
functions.markAsNeeded( options.ref_eq = getNonGC( "ref_eq", lineNumber ) );
}
return numeric;
}
@ -496,7 +496,7 @@ public abstract class WasmCodeBuilder {
virtualCall.setVariableIndexOfThis( varIndex );
instructions.add( virtualCall );
if( !options.useGC() ) {
functions.markAsNeeded( GET_I32, true );
functions.markAsNeeded( GET_I32 );
functions.markAsImport( GET_I32, GET_I32.getAnnotation() );
}
}
@ -595,7 +595,7 @@ public abstract class WasmCodeBuilder {
if( !options.useGC() ) {
SyntheticFunctionName name = structInst.createNonGcFunction();
if( name != null ) {
functions.markAsNeeded( name, true );
functions.markAsNeeded( name );
functions.markAsImport( name, name.getAnnotation() );
}
}