mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
WASM: fix metadata intrinsics
This commit is contained in:
parent
9e6061c3f1
commit
f347de44a9
|
@ -20,10 +20,6 @@ import java.util.Arrays;
|
|||
import org.teavm.classlib.impl.Base46;
|
||||
import org.teavm.classlib.impl.CharFlow;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public final class UnicodeHelper {
|
||||
private UnicodeHelper() {
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ public final class Example {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Integer.parseInt("123"));
|
||||
testFibonacci();
|
||||
testClasses();
|
||||
testVirtualCall();
|
||||
|
@ -39,7 +38,7 @@ public final class Example {
|
|||
testArrayIsObject();
|
||||
testIsAssignableFrom();
|
||||
testExceptions();
|
||||
//testBigInteger();
|
||||
testBigInteger();
|
||||
testGC();
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public class BinaryWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private static int align(int address, int alignment) {
|
||||
public static int align(int address, int alignment) {
|
||||
if (address == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -406,7 +406,7 @@ public class WasmClassGenerator {
|
|||
data.cls = cls;
|
||||
|
||||
for (FieldReader field : cls.getFields()) {
|
||||
int desiredAlignment = getDesiredAlignment(field.getType());
|
||||
int desiredAlignment = getTypeSize(field.getType());
|
||||
if (field.hasModifier(ElementModifier.STATIC)) {
|
||||
DataType type = asDataType(field.getType());
|
||||
data.fieldLayout.put(field.getName(), binaryWriter.append(type.createValue()));
|
||||
|
@ -450,7 +450,7 @@ public class WasmClassGenerator {
|
|||
return ((base - 1) / alignment + 1) * alignment;
|
||||
}
|
||||
|
||||
private int getDesiredAlignment(ValueType type) {
|
||||
public static int getTypeSize(ValueType type) {
|
||||
if (type instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) type).getKind()) {
|
||||
case BOOLEAN:
|
||||
|
|
|
@ -95,7 +95,7 @@ class BuildTimeResourceProxyBuilder {
|
|||
methods.put(method, (proxy, args) -> descriptor);
|
||||
break;
|
||||
case "getValues":
|
||||
methods.put(method, (proxy, args) -> initialData.clone());
|
||||
methods.put(method, (proxy, args) -> proxy.data.clone());
|
||||
break;
|
||||
case "getPropertyIndex":
|
||||
methods.put(method, (proxy, args) -> propertyIndexes.getOrDefault(args[0], -1));
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
*/
|
||||
package org.teavm.platform.plugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
class BuildTimeResourceSetter implements BuildTimeResourceMethod {
|
||||
private int index;
|
||||
|
||||
|
|
|
@ -15,8 +15,13 @@
|
|||
*/
|
||||
package org.teavm.platform.plugin;
|
||||
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.backend.javascript.TeaVMJavaScriptHost;
|
||||
import org.teavm.backend.wasm.TeaVMWasmHost;
|
||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
|
||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.vm.spi.TeaVMHost;
|
||||
import org.teavm.vm.spi.TeaVMPlugin;
|
||||
|
||||
|
@ -28,6 +33,8 @@ public class PlatformPlugin implements TeaVMPlugin {
|
|||
host.add(new ResourceTransformer());
|
||||
host.add(new ResourceAccessorTransformer(host));
|
||||
host.add(new ResourceAccessorDependencyListener());
|
||||
} else {
|
||||
host.add(new StringAmplifierTransformer());
|
||||
}
|
||||
|
||||
TeaVMWasmHost wasmHost = host.getExtension(TeaVMWasmHost.class);
|
||||
|
@ -35,6 +42,18 @@ public class PlatformPlugin implements TeaVMPlugin {
|
|||
wasmHost.add(ctx -> new MetadataIntrinsic(ctx.getClassSource(), ctx.getClassLoader(), ctx.getServices(),
|
||||
ctx.getProperties()));
|
||||
wasmHost.add(ctx -> new ResourceReadIntrinsic(ctx.getClassSource(), ctx.getClassLoader()));
|
||||
|
||||
wasmHost.add(ctx -> new WasmIntrinsic() {
|
||||
@Override
|
||||
public boolean isApplicable(MethodReference methodReference) {
|
||||
return methodReference.getClassName().equals(StringAmplifier.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) {
|
||||
return manager.generate(invocation.getArguments().get(0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
host.add(new AsyncMethodProcessor());
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.backend.wasm.binary.BinaryWriter;
|
||||
import org.teavm.backend.wasm.generate.WasmClassGenerator;
|
||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
|
||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
|
@ -119,8 +121,8 @@ public class ResourceReadIntrinsic implements WasmIntrinsic {
|
|||
for (Method method : methods) {
|
||||
MethodReference methodRef = MethodReference.parse(method);
|
||||
ValueType propertyType = methodRef.getReturnType();
|
||||
int size = getPropertySize(propertyType);
|
||||
currentOffset = ((currentOffset + size - 1) / size + 1) * size;
|
||||
int size = WasmClassGenerator.getTypeSize(propertyType);
|
||||
currentOffset = BinaryWriter.align(currentOffset, size);
|
||||
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor();
|
||||
propertyDescriptor.offset = currentOffset;
|
||||
|
@ -131,26 +133,6 @@ public class ResourceReadIntrinsic implements WasmIntrinsic {
|
|||
}
|
||||
}
|
||||
|
||||
private int getPropertySize(ValueType type) {
|
||||
if (type instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) type).getKind()) {
|
||||
case BOOLEAN:
|
||||
case BYTE:
|
||||
return 1;
|
||||
case SHORT:
|
||||
case CHARACTER:
|
||||
return 2;
|
||||
case INTEGER:
|
||||
case FLOAT:
|
||||
return 4;
|
||||
case LONG:
|
||||
case DOUBLE:
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
static class StructureDescriptor {
|
||||
ResourceTypeDescriptor typeDescriptor;
|
||||
Map<MethodReference, PropertyDescriptor> layout = new HashMap<>();
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2017 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.platform.plugin;
|
||||
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
|
||||
final class StringAmplifier {
|
||||
private StringAmplifier() {
|
||||
}
|
||||
|
||||
@PluggableDependency(StringAmplifierDependencyPlugin.class)
|
||||
static native String amplify(String string);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2017 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.platform.plugin;
|
||||
|
||||
import org.teavm.dependency.DependencyAgent;
|
||||
import org.teavm.dependency.DependencyPlugin;
|
||||
import org.teavm.dependency.MethodDependency;
|
||||
import org.teavm.model.CallLocation;
|
||||
|
||||
public class StringAmplifierDependencyPlugin implements DependencyPlugin {
|
||||
@Override
|
||||
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||
method.getResult().propagate(agent.getType("java.lang.String"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2017 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.platform.plugin;
|
||||
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.ClassHolderTransformer;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.Instruction;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.Variable;
|
||||
import org.teavm.model.instructions.InvocationType;
|
||||
import org.teavm.model.instructions.InvokeInstruction;
|
||||
import org.teavm.platform.metadata.Resource;
|
||||
|
||||
public class StringAmplifierTransformer implements ClassHolderTransformer {
|
||||
@Override
|
||||
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
if (method.getProgram() != null) {
|
||||
transformProgram(innerSource, method.getProgram());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void transformProgram(ClassReaderSource classSource, Program program) {
|
||||
for (BasicBlock block : program.getBasicBlocks()) {
|
||||
for (Instruction instruction : block) {
|
||||
if (!(instruction instanceof InvokeInstruction)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
InvokeInstruction invoke = (InvokeInstruction) instruction;
|
||||
if (invoke.getReceiver() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MethodReference method = invoke.getMethod();
|
||||
String owningClass = method.getClassName();
|
||||
if (classSource.isSuperType(Resource.class.getName(), owningClass).orElse(false)) {
|
||||
if (method.getReturnType().isObject(String.class)) {
|
||||
Variable var = program.createVariable();
|
||||
InvokeInstruction amplifyInstruction = new InvokeInstruction();
|
||||
amplifyInstruction.setMethod(new MethodReference(StringAmplifier.class, "amplify",
|
||||
String.class, String.class));
|
||||
amplifyInstruction.setType(InvocationType.SPECIAL);
|
||||
amplifyInstruction.getArguments().add(var);
|
||||
amplifyInstruction.setReceiver(invoke.getReceiver());
|
||||
amplifyInstruction.setLocation(invoke.getLocation());
|
||||
|
||||
invoke.setReceiver(var);
|
||||
invoke.insertNext(amplifyInstruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user