Skip to content

Commit

Permalink
[WASM] Allow declaring native wasm arrays.
Browse files Browse the repository at this point in the history
Arrays of native types will be considered as native wasm arrays.

PiperOrigin-RevId: 571345388
  • Loading branch information
rluble authored and copybara-github committed Oct 6, 2023
1 parent 5023572 commit 49bac39
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,22 @@ public boolean isUntypedArray() {
* Returns true for arrays where raw wasm array representation is enough. These arrays are located
* in {@see javaemul.internal.WasmArrays}.
*/
public abstract boolean isNativeWasmArray();
public abstract boolean isMarkedAsNativeWasmArray();

@Override
public boolean isNativeWasmArray() {
if (isMarkedAsNativeWasmArray()) {
return true;
}

if (getComponentTypeDescriptor().toRawTypeDescriptor() instanceof DeclaredTypeDescriptor) {
DeclaredTypeDescriptor componentTypeDescriptor =
(DeclaredTypeDescriptor) getComponentTypeDescriptor().toRawTypeDescriptor();
return componentTypeDescriptor.getTypeDeclaration().getWasmInfo() != null;
}

return false;
}

@Override
public abstract boolean isNullable();
Expand Down Expand Up @@ -228,7 +243,7 @@ public static Builder newBuilder() {
return new AutoValue_ArrayTypeDescriptor.Builder()
// Default values.
.setNullable(true)
.setNativeWasmArray(false);
.setMarkedAsNativeWasmArray(false);
}

/** Builder for an ArrayTypeDescriptor. */
Expand All @@ -242,7 +257,7 @@ public static Builder from(ArrayTypeDescriptor arrayTypeDescriptor) {

public abstract Builder setNullable(boolean isNullable);

public abstract Builder setNativeWasmArray(boolean wasmNative);
public abstract Builder setMarkedAsNativeWasmArray(boolean wasmNative);

abstract ArrayTypeDescriptor autoBuild();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ public boolean isAnnotatedWithFunctionalInterface() {
return false;
}

/** Returns whether the described type is a wasm native array. */
public boolean isNativeWasmArray() {
return false;
}

/**
* Returns the mangled name of a type.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ String getWasmTypeName(TypeDescriptor typeDescriptor) {
if (typeDescriptor.isArray()) {
ArrayTypeDescriptor arrayTypeDescriptor = (ArrayTypeDescriptor) typeDescriptor;
if (arrayTypeDescriptor.isNativeWasmArray()) {
return getWasmTypeName(arrayTypeDescriptor.getComponentTypeDescriptor()) + ".array";
String wasmTypeName = getWasmTypeName(arrayTypeDescriptor.getComponentTypeDescriptor());
// Make sure the resulting type name always has $ prefix.
String prefix = wasmTypeName.startsWith("$") ? "" : "$";
return format("%s%s.array", prefix, wasmTypeName);
}
return getWasmTypeName(TypeDescriptors.getWasmArrayType(arrayTypeDescriptor));
}
Expand All @@ -172,9 +175,6 @@ private static String getTypeSignature(TypeDescriptor typeDescriptor) {
}

public String getWasmEmptyArrayGlobalName(ArrayTypeDescriptor arrayTypeDescriptor) {
checkArgument(
arrayTypeDescriptor.isPrimitiveArray()
|| TypeDescriptors.isJavaLangObject(arrayTypeDescriptor.getComponentTypeDescriptor()));
return "$__emptyArray_" + getWasmTypeName(arrayTypeDescriptor);
}
/** Returns the name of the global that stores the itable for a Java type. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -824,11 +824,23 @@ private void emitWasmStruct(

private List<ArrayTypeDescriptor> collectUsedNativeArrayTypes(Library library) {
Set<ArrayTypeDescriptor> usedArrayTypes = new LinkedHashSet<>();
// Collect native arrays from fields and variables; this covers all scenarios.
library.accept(
// TODO(b/303659726): Generalize a type visitor that could be used here and other places
// like in ImportGatherer. Or consider emitting the one dimensional array type for all
// native types.
new AbstractVisitor() {
@Override
public void exitField(Field field) {
TypeDescriptor typeDescriptor = field.getDescriptor().getTypeDescriptor();
collectIfArrayType(field.getDescriptor().getTypeDescriptor());
}

@Override
public void exitVariable(Variable variable) {
collectIfArrayType(variable.getTypeDescriptor());
}

private void collectIfArrayType(TypeDescriptor typeDescriptor) {
if (!typeDescriptor.isArray()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ private static Variable markVariableTypeDescriptorAsNative(Variable original) {
}

private static ArrayTypeDescriptor markArrayTypeDescriptorAsNative(ArrayTypeDescriptor original) {
return ArrayTypeDescriptor.Builder.from(original).setNativeWasmArray(true).build();
return ArrayTypeDescriptor.Builder.from(original).setMarkedAsNativeWasmArray(true).build();
}

private static TypeDescriptor maybeMarkTypeDescriptorAsNative(TypeDescriptor original) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
* <p>This test will be removed when all Wasm features are implemented and all integration tests are
* enabled for Wasm.
*/
@SuppressWarnings("unusable-by-js")
public class Main {

public static void main(String... args) throws Exception {
testWasmAnnotation();
testClassLiterals();
testArrayInstanceOf();
testArrayGetClass();
testNativeArrays();
}

private static void testWasmAnnotation() {
Expand Down Expand Up @@ -139,4 +141,27 @@ private static void testArrayGetClass() {
assertEquals(Object[].class, objectArray.getClass());
assertEquals(Object.class, objectArray.getClass().getComponentType());
}

@Wasm("i31")
interface I31Ref {}

@Wasm("ref.i31")
private static native I31Ref toI31Ref(int value);

@Wasm("i31.get_s")
private static native int i31GetS(I31Ref value);

private static void testNativeArrays() {
I31Ref[] i31Refs = new I31Ref[10];

I31Ref two = toI31Ref(2);
i31Refs[1] = two;
assertTrue(i31GetS(i31Refs[1]) == 2);
for (int i = 0; i < i31Refs.length; i++) {
i31Refs[i] = toI31Ref(i);
}
for (int i = 0; i < i31Refs.length; i++) {
assertTrue(i31GetS(i31Refs[i]) == i);
}
}
}

0 comments on commit 49bac39

Please sign in to comment.