diff --git a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java index d603ddc..361c992 100644 --- a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java +++ b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2020 Volker Berlin (i-net software) + * Copyright 2018 - 2021 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. @@ -135,7 +135,7 @@ class FunctionManager { states.remove( name ); states.put( name, state ); } - markAsNeeded( name ); + markAsNeeded( name, !name.istStatic() ); } /** @@ -143,15 +143,18 @@ class FunctionManager { * * @param name * the function name + * @param needThisParameter + * if this function need additional to the parameter of the signature an extra "this" parameter * @return the real function name */ - FunctionName markAsNeeded( @Nonnull FunctionName name ) { + FunctionName markAsNeeded( @Nonnull FunctionName name, boolean needThisParameter ) { FunctionState state = getOrCreate( name ); if( state.state == State.None ) { if( isFinish ) { throw new WasmException( "Prepare was already finish: " + name.signatureName, -1 ); } state.state = State.Needed; + state.needThisParameter = needThisParameter; JWebAssembly.LOGGER.fine( "\t\tcall: " + name.signatureName ); usedClasses.add( name.className ); } @@ -163,10 +166,8 @@ class FunctionManager { * * @param name * the function name - * @param needThisParameter - * if this function need additional to the parameter of the signature an extra "this" parameter */ - void markAsScanned( @Nonnull FunctionName name, boolean needThisParameter ) { + void markAsScanned( @Nonnull FunctionName name ) { FunctionState state = getOrCreate( name ); switch( state.state ) { case None: @@ -174,7 +175,6 @@ class FunctionManager { state.state = State.Scanned; break; } - state.needThisParameter = needThisParameter; } /** diff --git a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java index b25c463..93b43b0 100644 --- a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java @@ -362,14 +362,14 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { break; case 108: // idiv if( getOptions().useEH() ) { - addCallInstruction( new FunctionName( "de/inetsoftware/jwebassembly/module/WasmEmbbeddedCode", "idiv", "(II)I" ), codePos, lineNumber ); + addCallInstruction( new FunctionName( "de/inetsoftware/jwebassembly/module/WasmEmbbeddedCode", "idiv", "(II)I" ), false, codePos, lineNumber ); } else { addNumericInstruction( NumericOperator.div, ValueType.i32, codePos, lineNumber ); } break; case 109: // ldiv if( getOptions().useEH() ) { - addCallInstruction( new FunctionName( "de/inetsoftware/jwebassembly/module/WasmEmbbeddedCode", "ldiv", "(JJ)J" ), codePos, lineNumber ); + addCallInstruction( new FunctionName( "de/inetsoftware/jwebassembly/module/WasmEmbbeddedCode", "ldiv", "(JJ)J" ), false, codePos, lineNumber ); } else { addNumericInstruction( NumericOperator.div, ValueType.i64, codePos, lineNumber ); } @@ -388,11 +388,11 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { break; case 114: // frem //helper function like: (a - (int)(a / b) * (float)b) - addCallInstruction( new WatCodeSyntheticFunctionName( "frem", "local.get 0 local.get 0 local.get 1 f32.div i32.trunc_sat_f32_s f32.convert_i32_s local.get 1 f32.mul f32.sub return", ValueType.f32, ValueType.f32, null, ValueType.f32 ), codePos, lineNumber ); + addCallInstruction( new WatCodeSyntheticFunctionName( "frem", "local.get 0 local.get 0 local.get 1 f32.div i32.trunc_sat_f32_s f32.convert_i32_s local.get 1 f32.mul f32.sub return", ValueType.f32, ValueType.f32, null, ValueType.f32 ), false, codePos, lineNumber ); break; case 115: // drem //helper function like: (a - (long)(a / b) * (double)b) - addCallInstruction( new WatCodeSyntheticFunctionName( "drem", "local.get 0 local.get 0 local.get 1 f64.div i64.trunc_sat_f64_s f64.convert_i64_s local.get 1 f64.mul f64.sub return", ValueType.f64, ValueType.f64, null, ValueType.f64 ), codePos, lineNumber ); + addCallInstruction( new WatCodeSyntheticFunctionName( "drem", "local.get 0 local.get 0 local.get 1 f64.div i64.trunc_sat_f64_s f64.convert_i64_s local.get 1 f64.mul f64.sub return", ValueType.f64, ValueType.f64, null, ValueType.f64 ), false, codePos, lineNumber ); break; case 116: // ineg addConstInstruction( -1, ValueType.i32, codePos, lineNumber ); @@ -621,10 +621,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { addCallVirtualInstruction( funcName, codePos, lineNumber ); break; case 183: - addCallInstruction( funcName, codePos, lineNumber ); + addCallInstruction( funcName, true, codePos, lineNumber ); break; case 184: - addCallInstruction( funcName, codePos, lineNumber ); + addCallInstruction( funcName, false, codePos, lineNumber ); break; case 185: addCallInterfaceInstruction( funcName, codePos, lineNumber ); diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 6215885..45d09da 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -208,7 +208,7 @@ public class ModuleGenerator { } else { functions.markAsImport( synth, synth.getAnnotation() ); } - functions.markAsScanned( next, !synth.istStatic() ); + functions.markAsScanned( next ); continue; } @@ -224,11 +224,8 @@ public class ModuleGenerator { } if( method != null ) { createInstructions( functions.replace( next, method ) ); - boolean needThisParameter = !method.isStatic() // if not static there is a not declared THIS parameter - || "".equals( method.getName() ) // constructor method need also the THIS parameter also if marked as static - /*|| (method.isLambda() )*/; // lambda functions are static but will call with a THIS parameter which need be removed from stack - functions.markAsScanned( next, needThisParameter ); - if( needThisParameter ) { + functions.markAsScanned( next ); + if( functions.needThisParameter( next ) ) { types.valueOf( next.className ); // for the case that the type unknown yet } continue; @@ -240,7 +237,7 @@ public class ModuleGenerator { method = superClassFile.getMethod( next.methodName, next.signature ); if( method != null ) { FunctionName name = new FunctionName( method ); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !method.isStatic() ); functions.setAlias( next, name ); continue NEXT; // we have found a super method } @@ -256,7 +253,7 @@ public class ModuleGenerator { method = iClassFile.getMethod( next.methodName, next.signature ); if( method != null ) { FunctionName name = new FunctionName( method ); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !method.isStatic() ); functions.setAlias( next, name ); continue NEXT; // we have found a super method } @@ -344,7 +341,7 @@ public class ModuleGenerator { if( classFile != null ) { MethodInfo method = classFile.getMethod( "", "()V" ); if( method != null ) { - functions.markAsNeeded( new FunctionName( method ) ); + functions.markAsNeeded( new FunctionName( method ), false ); } } } @@ -360,7 +357,7 @@ public class ModuleGenerator { // add the start function/section only if there are static code if( functions.getWriteLaterClinit().hasNext() ) { FunctionName start = new StaticCodeBuilder( writer.options, classFileLoader, javaCodeBuilder ).createStartFunction(); - functions.markAsNeeded( start ); + functions.markAsNeeded( start, false ); writeMethodSignature( start, FunctionType.Start, null ); } } @@ -474,7 +471,7 @@ public class ModuleGenerator { if( !method.isStatic() ) { throw new WasmException( "Export method must be static: " + name.fullName, -1 ); } - functions.markAsNeeded( name ); + functions.markAsNeeded( name, false ); return; } } catch( Exception ioex ) { diff --git a/src/de/inetsoftware/jwebassembly/module/StaticCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/StaticCodeBuilder.java index d3c049e..e564e3d 100644 --- a/src/de/inetsoftware/jwebassembly/module/StaticCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/StaticCodeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Volker Berlin (i-net software) + * Copyright 2020 - 2021 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. @@ -85,7 +85,7 @@ class StaticCodeBuilder { while( !clinits.isEmpty() ) { FunctionName name = clinits.pop(); - watParser.addCallInstruction( name, 0, -1 ); + watParser.addCallInstruction( name, false, 0, -1 ); scanAndPatchIfNeeded( name ); } return watParser; diff --git a/src/de/inetsoftware/jwebassembly/module/StringManager.java b/src/de/inetsoftware/jwebassembly/module/StringManager.java index 7a45182..8e98bac 100644 --- a/src/de/inetsoftware/jwebassembly/module/StringManager.java +++ b/src/de/inetsoftware/jwebassembly/module/StringManager.java @@ -1,5 +1,5 @@ /* - Copyright 2019 - 2020 Volker Berlin (i-net software) + Copyright 2019 - 2021 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. @@ -84,7 +84,7 @@ public class StringManager extends LinkedHashMap { } }; functions.markAsNeededAndReplaceIfExists( offsetFunction ); - functions.markAsNeeded( stringConstantFunction ); + functions.markAsNeeded( stringConstantFunction, false ); } return stringConstantFunction; diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index cd5553c..c98b82d 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -254,7 +254,7 @@ public class TypeManager { return "i32.const " + typeTableOffset; } }; - options.functions.markAsNeeded( offsetFunction ); + options.functions.markAsNeeded( offsetFunction, !offsetFunction.istStatic() ); return offsetFunction; } @@ -804,7 +804,7 @@ public class TypeManager { if( func.methodName.equals( funcName.methodName ) && func.signature.equals( funcName.signature ) ) { if( !isDefault || functions.getITableIndex( func ) >= 0 ) { vtable.set( idx, funcName ); // use the override method - functions.markAsNeeded( funcName ); // mark all overridden methods also as needed if the super method is used + functions.markAsNeeded( funcName, true ); // mark all overridden methods also as needed if the super method is used } break; } @@ -891,7 +891,7 @@ public class TypeManager { if( method != null ) { FunctionName methodName = new FunctionName( method ); - functions.markAsNeeded( methodName ); + functions.markAsNeeded( methodName, !method.isStatic() ); if( iMethods == null ) { interfaceMethods.put( type, iMethods = new ArrayList<>() ); } @@ -1210,7 +1210,7 @@ public class TypeManager { codebuilder.addStructInstruction( StructOperator.GET, name, paramFields.get( i ), 0, -1 ); } - codebuilder.addCallInstruction( syntheticLambdaFunctionName, 0, -1 ); + codebuilder.addCallInstruction( syntheticLambdaFunctionName, false, 0, -1 ); return watParser; } }; diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index a71a1ee..bd3c726 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -477,7 +477,7 @@ public abstract class WasmCodeBuilder { Integer id = types.valueOf( className ).getClassIndex(); FunctionName name = types.getClassConstantFunction(); instructions.add( new WasmConstInstruction( id, ValueType.i32, javaCodePos, lineNumber ) ); - addCallInstruction( name, javaCodePos, lineNumber ); + addCallInstruction( name, false, javaCodePos, lineNumber ); } else { //TODO There can be ConstantClass, MethodType and MethodHandle throw new WasmException( "Class constants are not supported. : " + value, lineNumber ); @@ -520,7 +520,7 @@ public abstract class WasmCodeBuilder { WasmNumericInstruction numeric = new WasmNumericInstruction( numOp, valueType, javaCodePos, lineNumber ); instructions.add( numeric ); if( !options.useGC() && options.ref_eq == null && (numOp == NumericOperator.ref_eq || numOp == NumericOperator.ref_ne ) ) { - functions.markAsNeeded( options.ref_eq = getNonGC( "ref_eq", lineNumber ) ); + functions.markAsNeeded( options.ref_eq = getNonGC( "ref_eq", lineNumber ), false ); } return numeric; } @@ -549,9 +549,8 @@ public abstract class WasmCodeBuilder { * @param lineNumber * the line number in the Java source code */ - protected void addCallInstruction( FunctionName name, int javaCodePos, int lineNumber ) { - name = functions.markAsNeeded( name ); - boolean needThisParameter = functions.needThisParameter( name ); + protected void addCallInstruction( FunctionName name, boolean needThisParameter, int javaCodePos, int lineNumber ) { + name = functions.markAsNeeded( name, needThisParameter ); WasmCallInstruction instruction = new WasmCallInstruction( name, javaCodePos, lineNumber, types, needThisParameter ); if( "".equals( name.methodName ) ) { @@ -642,7 +641,7 @@ public abstract class WasmCodeBuilder { * the line number in the Java source code */ protected void addCallVirtualInstruction( FunctionName name, int javaCodePos, int lineNumber ) { - name = functions.markAsNeeded( name ); + name = functions.markAsNeeded( name, true ); addCallIndirectInstruction( new WasmCallVirtualInstruction( name, javaCodePos, lineNumber, types, options ) ); options.getCallVirtual(); // mark the function as needed functions.markClassAsUsed( name.className ); @@ -658,7 +657,7 @@ public abstract class WasmCodeBuilder { * the line number in the Java source code */ protected void addCallInterfaceInstruction( FunctionName name, int javaCodePos, int lineNumber ) { - name = functions.markAsNeeded( name ); + name = functions.markAsNeeded( name, true ); addCallIndirectInstruction( new WasmCallInterfaceInstruction( name, javaCodePos, lineNumber, types, options ) ); options.getCallInterface(); // mark the function as needed functions.markClassAsUsed( name.className ); @@ -773,7 +772,7 @@ public abstract class WasmCodeBuilder { instructions.add( arrayInst ); SyntheticFunctionName name = arrayInst.createNonGcFunction( useGC ); if( name != null ) { - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !name.istStatic() ); functions.markAsImport( name, name.getAnnotation() ); } } @@ -809,7 +808,7 @@ public abstract class WasmCodeBuilder { */ protected void addMultiNewArrayInstruction( int dim, ArrayType type, int javaCodePos, int lineNumber ) { MultiArrayFunctionName name = new MultiArrayFunctionName( dim, type ); - addCallInstruction( name, javaCodePos, lineNumber ); + addCallInstruction( name, false, javaCodePos, lineNumber ); } /** @@ -846,7 +845,7 @@ public abstract class WasmCodeBuilder { if( !options.useGC() ) { SyntheticFunctionName name = structInst.createNonGcFunction(); if( name != null ) { - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !name.istStatic() ); functions.markAsImport( name, name.getAnnotation() ); } } @@ -881,7 +880,7 @@ public abstract class WasmCodeBuilder { } while( true ); StructType interfaceType = (StructType)parser.next(); LambdaType type = types.lambdaType( method, params, interfaceType, interfaceMethodName ); - functions.markAsNeeded( type.getLambdaMethod() ); + functions.markAsNeeded( type.getLambdaMethod(), true ); String lambdaTypeName = type.getName(); // Create the instance of the synthetic lambda class and save the parameters in fields diff --git a/src/de/inetsoftware/jwebassembly/module/WasmOptions.java b/src/de/inetsoftware/jwebassembly/module/WasmOptions.java index 9ce6fbe..b065f3c 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmOptions.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmOptions.java @@ -126,7 +126,7 @@ public class WasmOptions { if( get_i32 == null ) { SyntheticFunctionName name; get_i32 = name = new JavaScriptSyntheticFunctionName( "NonGC", "get_i32", () -> "(a,i) => a[i]", ValueType.externref, ValueType.i32, null, ValueType.i32 ); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !name.istStatic() ); functions.markAsImport( name, name.getAnnotation() ); } } @@ -142,7 +142,7 @@ public class WasmOptions { FunctionName name = callVirtual; if( name == null ) { callVirtual = name = types.createCallVirtual(); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, false ); registerGet_i32(); } return name; @@ -159,7 +159,7 @@ public class WasmOptions { FunctionName name = callInterface; if( name == null ) { callInterface = name = types.createCallInterface(); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, false ); registerGet_i32(); } return name; @@ -176,7 +176,7 @@ public class WasmOptions { SyntheticFunctionName name = instanceOf; if( name == null ) { instanceOf = name = types.createInstanceOf(); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !name.istStatic() ); registerGet_i32(); } return name; @@ -193,7 +193,7 @@ public class WasmOptions { SyntheticFunctionName name = cast; if( name == null ) { cast = name = types.createCast(); - functions.markAsNeeded( name ); + functions.markAsNeeded( name, !name.istStatic() ); getInstanceOf(); } return name; diff --git a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java index 59179a9..ebb2f6b 100644 --- a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java +++ b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java @@ -234,7 +234,7 @@ public class WatParser extends WasmCodeBuilder { } while ( !")".equals( str ) ); builder.append( get( tokens, ++i ) ); FunctionName name = new FunctionName( builder.substring( 1 ) ); - addCallInstruction( name, javaCodePos, lineNumber ); + addCallInstruction( name, false, javaCodePos, lineNumber ); } catch( Exception ex ) { throw WasmException.create( "The syntax for a function name is $package.ClassName.methodName(paramSignature)returnSignature", ex ); }