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"); * 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.
@ -104,9 +104,13 @@ public class FunctionManager {
* *
* @param name * @param name
* the function name * the function name
* @param needThisParameter
* if this function need additional to the signature a this parameter
*/ */
void markAsScanned( FunctionName name ) { void markAsScanned( FunctionName name, boolean needThisParameter ) {
getOrCreate( name ).state = State.Scanned; FunctionState state = getOrCreate( name );
state.state = State.Scanned;
state.needThisParameter = needThisParameter;
} }
/** /**
@ -124,11 +128,9 @@ public class FunctionManager {
* *
* @param name * @param name
* the function name * the function name
* @param isStatic
* true, if the method is static
* @return the real function name * @return the real function name
*/ */
FunctionName markAsNeeded( FunctionName name, boolean isStatic ) { FunctionName markAsNeeded( FunctionName name ) {
FunctionState state = getOrCreate( name ); FunctionState state = getOrCreate( name );
if( state.state == State.None ) { if( state.state == State.None ) {
if( isFinish ) { if( isFinish ) {
@ -136,7 +138,6 @@ public class FunctionManager {
} }
state.state = State.Needed; state.state = State.Needed;
} }
state.isStatic = isStatic;
return state.alias == null ? name : state.alias; return state.alias == null ? name : state.alias;
} }
@ -269,8 +270,8 @@ public class FunctionManager {
* the function name * the function name
* @return true, if the function is static * @return true, if the function is static
*/ */
boolean isStatic( FunctionName name ) { boolean needThisParameter( FunctionName name ) {
return getOrCreate( name ).isStatic; return getOrCreate( name ).needThisParameter;
} }
/** /**
@ -355,7 +356,7 @@ public class FunctionManager {
private int functionIdx = -1; private int functionIdx = -1;
private boolean isStatic; private boolean needThisParameter;
} }
private static enum State { private static enum State {

View File

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

View File

@ -80,11 +80,9 @@ class WasmCallInstruction extends WasmInstruction {
* *
* @param functions * @param functions
* the function manager * the function manager
* @param isStatic
* true, if the method is static
*/ */
void markAsNeeded( @Nonnull FunctionManager functions, boolean isStatic ) { void markAsNeeded( @Nonnull FunctionManager functions ) {
name = functions.markAsNeeded( name, isStatic && !name.methodName.equals( "<init>" ) ); // a constructor is like static call but has a hidden "this" parameter. 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"); * 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.
@ -391,7 +391,7 @@ public abstract class WasmCodeBuilder {
WasmNumericInstruction numeric = new WasmNumericInstruction( numOp, valueType, javaCodePos, lineNumber ); WasmNumericInstruction numeric = new WasmNumericInstruction( numOp, valueType, javaCodePos, lineNumber );
instructions.add( numeric ); instructions.add( numeric );
if( !options.useGC() && numOp == NumericOperator.ref_eq ) { 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; return numeric;
} }
@ -496,7 +496,7 @@ public abstract class WasmCodeBuilder {
virtualCall.setVariableIndexOfThis( varIndex ); virtualCall.setVariableIndexOfThis( varIndex );
instructions.add( virtualCall ); instructions.add( virtualCall );
if( !options.useGC() ) { if( !options.useGC() ) {
functions.markAsNeeded( GET_I32, true ); functions.markAsNeeded( GET_I32 );
functions.markAsImport( GET_I32, GET_I32.getAnnotation() ); functions.markAsImport( GET_I32, GET_I32.getAnnotation() );
} }
} }
@ -595,7 +595,7 @@ public abstract class WasmCodeBuilder {
if( !options.useGC() ) { if( !options.useGC() ) {
SyntheticFunctionName name = structInst.createNonGcFunction(); SyntheticFunctionName name = structInst.createNonGcFunction();
if( name != null ) { if( name != null ) {
functions.markAsNeeded( name, true ); functions.markAsNeeded( name );
functions.markAsImport( name, name.getAnnotation() ); functions.markAsImport( name, name.getAnnotation() );
} }
} }