diff --git a/README.md b/README.md index 50133b0..dd8aeb4 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ The project is currently not production ready but you can run already some tests * [x] invoke instance method calls * [ ] invoke interface method calls * [ ] invoke dynamic method calls (lambdas) +* [x] invoke default method calls * [ ] String support * [ ] static constructors * [x] Optimizer - Optimize the WASM output of a single method after transpiling before writing to output diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 86028ce..741128f 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -228,6 +228,24 @@ public class ModuleGenerator { ConstantClass superClass = superClassFile.getSuperClass(); superClassFile = superClass == null ? null : classFileLoader.get( superClass.getName() ); } + + // search if there is a default implementation in an interface + superClassFile = classFile; + while( superClassFile != null ) { + for( ConstantClass iface : superClassFile.getInterfaces() ) { + ClassFile iClassFile = classFileLoader.get( iface.getName() ); + MethodInfo method = iClassFile.getMethod( next.methodName, next.signature ); + if( method != null ) { + FunctionName name = new FunctionName( method ); + functions.markAsNeeded( name ); + functions.setAlias( next, name ); + continue NEXT; // we have found a super method + } + } + ConstantClass superClass = superClassFile.getSuperClass(); + superClassFile = superClass == null ? null : classFileLoader.get( superClass.getName() ); + } + throw new WasmException( "Missing function: " + next.signatureName, -1 ); } } diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index 9b5d658..2ac7f25 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.annotation.Nonnull; import de.inetsoftware.classparser.ClassFile; +import de.inetsoftware.classparser.ClassFile.Type; import de.inetsoftware.classparser.ConstantClass; import de.inetsoftware.classparser.FieldInfo; import de.inetsoftware.classparser.MethodInfo; @@ -231,6 +232,11 @@ public class TypeManager { throw new WasmException( "Missing class: " + className, -1 ); } + // interface does not need to resolve + if( classFile.getType() == Type.Interface ) { + return; + } + { // list all used fields StructType type = types.structTypes.get( className ); diff --git a/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java b/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java index ec43dfc..302e974 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java +++ b/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java @@ -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. @@ -49,6 +49,7 @@ public class StructsNonGC extends AbstractBaseTest { addParam( list, script, "callVirtualMethod" ); addParam( list, script, "useGlobalObject" ); addParam( list, script, "multipleAssign" ); + addParam( list, script, "getDefaultValue" ); } rule.setTestParameters( list ); return list; @@ -136,9 +137,21 @@ public class StructsNonGC extends AbstractBaseTest { } return val.a; } + + @Export + static int getDefaultValue() { + Abc2 val = new Abc2(); + return val.getDefault(); + } } - static class Abc { + interface TestDefault { + default int getDefault() { + return 7; + } + } + + static class Abc implements TestDefault { int a; long b;