Skip to content

Commit

Permalink
#296 Test all variants of JEP 280 style string concatenations
Browse files Browse the repository at this point in the history
  • Loading branch information
mirkosertic committed Dec 7, 2019
1 parent cb9948d commit 3c11880
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package de.mirkosertic.bytecoder.classlib;

import de.mirkosertic.bytecoder.api.EmulatedByRuntime;
import de.mirkosertic.bytecoder.api.Export;

import java.lang.invoke.ConstantCallSite;
Expand Down Expand Up @@ -159,27 +160,39 @@ public static Locale defaultLocale() {
return new Locale("en", "US");
}

@EmulatedByRuntime
public static native boolean isChar(final MethodType aType, final int aParamIndex);

@EmulatedByRuntime
public static native boolean isFloat(final MethodType aType, final int aParamIndex);

@EmulatedByRuntime
public static native boolean isDouble(final MethodType aType, final int aParamIndex);

@EmulatedByRuntime
public static native boolean isBoolean(final MethodType aType, final int aParamIndex);

@EmulatedByRuntime
public static native boolean isInteger(final MethodType aType, final int aParamIndex);

@EmulatedByRuntime
public static native boolean isLong(final MethodType aType, final int aParamIndex);

@EmulatedByRuntime
public static native int reinterpretAsInt(final Object o);

@EmulatedByRuntime
public static native long reinterpretAsLong(final Object o);

@EmulatedByRuntime
public static native float reinterpretAsFloat(final Object o);

@EmulatedByRuntime
public static native double reinterpretAsDouble(final Object o);

@EmulatedByRuntime
public static native char reinterpretAsChar(final Object o);

@EmulatedByRuntime
public static native boolean reinterpretAsBoolean(final Object o);
}
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ public WASMCompileResult generateCodeFor(
if (theProvidingClass.emulatedByRuntime()) {
return;
}
if (t.emulatedByRuntime()) {
return;
}

// Native methods are imported via annotation
if (!t.getAccessFlags().isNative() && theProvidingClass.isOpaqueType()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,6 @@
*/
package de.mirkosertic.bytecoder.backend.wasm;

import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.call;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.currentMemory;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.f32;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.getGlobal;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.getLocal;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.i32;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.select;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.teeLocal;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.weakFunctionReference;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.weakFunctionTableReference;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import de.mirkosertic.bytecoder.allocator.AbstractAllocator;
import de.mirkosertic.bytecoder.allocator.Register;
import de.mirkosertic.bytecoder.backend.CompileOptions;
Expand Down Expand Up @@ -115,6 +94,7 @@
import de.mirkosertic.bytecoder.ssa.MemorySizeExpression;
import de.mirkosertic.bytecoder.ssa.MethodHandlesGeneratedLookupExpression;
import de.mirkosertic.bytecoder.ssa.MethodRefExpression;
import de.mirkosertic.bytecoder.ssa.MethodTypeArgumentCheckExpression;
import de.mirkosertic.bytecoder.ssa.MethodTypeExpression;
import de.mirkosertic.bytecoder.ssa.MinExpression;
import de.mirkosertic.bytecoder.ssa.NegatedExpression;
Expand All @@ -130,6 +110,7 @@
import de.mirkosertic.bytecoder.ssa.PutFieldExpression;
import de.mirkosertic.bytecoder.ssa.PutStaticExpression;
import de.mirkosertic.bytecoder.ssa.RegionNode;
import de.mirkosertic.bytecoder.ssa.ReinterpretAsNativeExpression;
import de.mirkosertic.bytecoder.ssa.ResolveCallsiteObjectExpression;
import de.mirkosertic.bytecoder.ssa.ReturnExpression;
import de.mirkosertic.bytecoder.ssa.ReturnValueExpression;
Expand All @@ -151,6 +132,27 @@
import de.mirkosertic.bytecoder.ssa.VariableAssignmentExpression;
import de.mirkosertic.bytecoder.stackifier.Stackifier;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.call;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.currentMemory;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.f32;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.getGlobal;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.getLocal;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.i32;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.select;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.teeLocal;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.weakFunctionReference;
import static de.mirkosertic.bytecoder.backend.wasm.ast.ConstExpressions.weakFunctionTableReference;

public class WASMSSAASTWriter {

public static String registerName(final Register r) {
Expand Down Expand Up @@ -808,9 +810,75 @@ private WASMValue toValue(final Value aValue) {
if (aValue instanceof PtrOfExpression) {
return ptrOfExpression((PtrOfExpression) aValue);
}
if (aValue instanceof MethodTypeArgumentCheckExpression) {
return methodTypeArgumentCheckExpression((MethodTypeArgumentCheckExpression) aValue);
}
if (aValue instanceof ReinterpretAsNativeExpression) {
return reinterpretAsNativeExpression((ReinterpretAsNativeExpression) aValue);
}
throw new IllegalStateException("Not supported : " + aValue);
}

private WASMValue methodTypeValue(final MethodTypeExpression aValue) {
final BytecodeMethodSignature theSignature = aValue.getSignature();
final String theMethodTypeFactoryName = WASMWriterUtils.toMethodName("methodTypeFactory", theSignature);
ExportableFunction theFactoryFunction;
try {
theFactoryFunction = module.functionIndex().firstByLabel(theMethodTypeFactoryName);
} catch (final Exception e) {
theFactoryFunction = module.getFunctions().newFunction(theMethodTypeFactoryName, PrimitiveType.i32);
final Local data = theFactoryFunction.newLocal("data", PrimitiveType.i32);
final int length = 1 + theSignature.getArguments().length;
theFactoryFunction.flow.setLocal(data, newArray(i32.c(length, null)), null);

final Expressions f = theFactoryFunction.flow;
final java.util.function.BiFunction<BytecodeTypeRef, Integer, Void> theAdder = (aType, aIndex) -> {
final int offset = 20 + aIndex * 4;
if (aType.isPrimitive()) {
final TypeRef.Native theNativeType = (TypeRef.Native) TypeRef.toType(aType);
// Negative number to indicate it is a primitive type
f.i32.store(offset, getLocal(data, null), i32.c(-theNativeType.ordinal(), null), aValue);
} else {
// Positive number with the id of the class
final BytecodeLinkedClass theLinkedClass = linkerContext.resolveClass((BytecodeObjectTypeRef) aType);
f.i32.store(offset, getLocal(data, null), i32.c(theLinkedClass.getUniqueId(), null), aValue);
}
return null;
};
// Return type and arguments
theAdder.apply(theSignature.getReturnType(), 0);
for (int i=0;i<theSignature.getArguments().length;i++) {
final BytecodeTypeRef theArgument = theSignature.getArguments()[i];
theAdder.apply(theArgument, i + 1);
}

theFactoryFunction.flow.ret(getLocal(data, null), null);
}
return call(theFactoryFunction, Collections.emptyList(), aValue);
}

private WASMValue methodTypeArgumentCheckExpression(final MethodTypeArgumentCheckExpression aExpression) {
final TypeRef.Native theExpectedType = aExpression.getExpectedType();
final Value theMethodType = aExpression.incomingDataFlows().get(0);
final Value theIndex = aExpression.incomingDataFlows().get(1);

final WASMValue thePtr = i32.add(toValue(theMethodType), i32.mul(toValue(theIndex), i32.c(4, aExpression), aExpression), aExpression);
final WASMValue theExpectedValue = i32.c(- theExpectedType.ordinal(), null);
final WASMValue theRead = i32.load(20, thePtr, aExpression);
return i32.eq(theExpectedValue, theRead, aExpression);
}

private WASMValue reinterpretAsNativeExpression(final ReinterpretAsNativeExpression aExpression) {
final Value theValue = aExpression.incomingDataFlows().get(0);
switch (aExpression.getExpectedType()) {
case FLOAT:
case DOUBLE:
return f32.convert_sI32(toValue(theValue), aExpression);
default:
return toValue(theValue);
}
}

private WASMValue ptrOfExpression(final PtrOfExpression aValue) {
return toValue(aValue.incomingDataFlows().get(0));
}
Expand Down Expand Up @@ -951,13 +1019,6 @@ private WASMValue currentException(final CurrentExceptionExpression aValue) {
return i32.c(0, aValue);
}

private WASMValue methodTypeValue(final MethodTypeExpression aValue) {
// print("(i32.const ");
// print(idResolver.resolveTypeIDForSignature(aValue.getSignature()));
// print(")");
return i32.c(0, aValue);
}

private WASMValue methodHandlesGeneratedLookupValue(final MethodHandlesGeneratedLookupExpression aValue) {
return i32.c(0, aValue);
}
Expand Down Expand Up @@ -1038,7 +1099,7 @@ private WASMValue stringValue(final StringValue aValue) {
return getGlobal(resolver.globalForStringFromPool(aValue), null);
}

private WASMExpression newArray(final Value aValue) {
private WASMExpression newArray(final WASMValue aValue) {
final String theMethodName = WASMWriterUtils.toMethodName(
BytecodeObjectTypeRef.fromRuntimeClass(MemoryManager.class),
"newArray",
Expand All @@ -1048,7 +1109,11 @@ private WASMExpression newArray(final Value aValue) {
final WeakFunctionReferenceCallable theClassInit = weakFunctionReference(theClassName + CLASSINITSUFFIX, null);
final Function theFunction = module.functionIndex().firstByLabel(theMethodName);

return call(theFunction, Arrays.asList(i32.c(0, null), toValue(aValue), call(theClassInit, Collections.emptyList(), null), weakFunctionTableReference(theClassName + VTABLEFUNCTIONSUFFIX, null)), null);
return call(theFunction, Arrays.asList(i32.c(0, null), aValue, call(theClassInit, Collections.emptyList(), null), weakFunctionTableReference(theClassName + VTABLEFUNCTIONSUFFIX, null)), null);
}

private WASMExpression newArray(final Value aValue) {
return newArray(toValue(aValue));
}

private WASMValue newArrayValue(final NewArrayExpression aValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package de.mirkosertic.bytecoder.core;

import de.mirkosertic.bytecoder.api.DelegatesTo;
import de.mirkosertic.bytecoder.api.EmulatedByRuntime;
import de.mirkosertic.bytecoder.graph.EdgeType;
import de.mirkosertic.bytecoder.graph.Node;

Expand Down Expand Up @@ -80,6 +81,10 @@ public <T extends BytecodeAttributeInfo> T attributeByType(final Class<T> aAttri
return null;
}

public boolean emulatedByRuntime() {
return getAttributes().getAnnotationByType(EmulatedByRuntime.class.getName()) != null;
}

public BytecodeMethodSignature getSignature() {
return signature;
}
Expand Down

0 comments on commit 3c11880

Please sign in to comment.