Fix dependency analysis and virtual method calls in html4j

This commit is contained in:
Alexey Andreev 2018-10-19 16:38:15 +03:00
parent 8a55510d4f
commit f10a2f73b8
3 changed files with 46 additions and 3 deletions

View File

@ -22,7 +22,8 @@ import org.teavm.vm.spi.TeaVMPlugin;
public class HTML4JPlugin implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
if (host.getExtension(TeaVMJavaScriptHost.class) == null) {
TeaVMJavaScriptHost jsHost = host.getExtension(TeaVMJavaScriptHost.class);
if (jsHost == null) {
return;
}
@ -31,7 +32,8 @@ public class HTML4JPlugin implements TeaVMPlugin {
host.add(new JavaScriptBodyTransformer());
host.add(new JCLHacks());
host.getExtension(TeaVMJavaScriptHost.class).add(new JavaScriptResourceInterceptor());
host.getExtension(TeaVMJavaScriptHost.class).add(new JavaScriptObjectEnhancer(bodyDependency));
jsHost.add(new JavaScriptResourceInterceptor());
jsHost.add(new JavaScriptObjectEnhancer(bodyDependency));
jsHost.addVirtualMethods(new JavaScriptBodyVirtualSupplier(bodyDependency));
}
}

View File

@ -40,6 +40,7 @@ import org.teavm.model.ValueType;
public class JavaScriptBodyDependency extends AbstractDependencyListener {
private DependencyNode allClassesNode;
private Map<MethodReference, Set<MethodReference>> reachedMethods = new HashMap<>();
Set<MethodReference> virtualMethods = new HashSet<>();
@Override
public void started(DependencyAgent agent) {
@ -138,6 +139,11 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
agent.linkMethod(JavaScriptConvGenerator.valueOfShortMethod, location).use();
agent.linkMethod(JavaScriptConvGenerator.valueOfLongMethod, location).use();
allClassesNode.propagate(agent.getType("java.lang.Integer"));
allClassesNode.propagate(agent.getType("java.lang.Float"));
allClassesNode.propagate(agent.getType("java.lang.Double"));
allClassesNode.propagate(agent.getType("java.lang.String"));
}
class GeneratorJsCallback extends JsCallback {
@ -198,10 +204,12 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
if (method == null) {
return;
}
virtualMethods.add(method.getReference());
MethodDependency methodDep = agent.linkMethod(method.getReference(), location);
methodDep.use();
for (int i = 0; i < methodDep.getParameterCount(); ++i) {
allClassesNode.connect(methodDep.getVariable(i));
allClassesNode.connect(methodDep.getVariable(i).getArrayItem());
}
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2018 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.html4j;
import org.teavm.backend.javascript.spi.VirtualMethodContributor;
import org.teavm.backend.javascript.spi.VirtualMethodContributorContext;
import org.teavm.model.MethodReference;
public class JavaScriptBodyVirtualSupplier implements VirtualMethodContributor {
private JavaScriptBodyDependency dependency;
public JavaScriptBodyVirtualSupplier(JavaScriptBodyDependency dependency) {
this.dependency = dependency;
}
@Override
public boolean isVirtual(VirtualMethodContributorContext context, MethodReference methodRef) {
return dependency.virtualMethods.contains(methodRef);
}
}