diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index c22f51a..4f75378 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -1,5 +1,5 @@ /* - Copyright 2018 - 2020 Volker Berlin (i-net software) + Copyright 2018 - 2021 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. @@ -62,7 +62,7 @@ public class TypeManager { /** * Name of field with array value. */ - static final String FIELD_VALUE = ".val"; + public static final String FIELD_VALUE = ".array"; /** * Byte position in the type description that contains the offset to the interfaces. Length 4 bytes. @@ -274,6 +274,7 @@ public class TypeManager { * the type name like java/lang/Object * @return the struct type */ + @Nonnull public StructType valueOf( String name ) { StructType type = structTypes.get( name ); if( type == null ) { @@ -301,6 +302,7 @@ public class TypeManager { * the component type of the array * @return the array type */ + @Nonnull public ArrayType arrayType( AnyType arrayType ) { ArrayType type = (ArrayType)structTypes.get( arrayType ); if( type == null ) { @@ -595,7 +597,7 @@ public class TypeManager { case array: HashSet allNeededFields = new HashSet<>(); listStructFields( "java/lang/Object", functions, types, classFileLoader, allNeededFields ); - fields.add( new NamedStorageType( ((ArrayType)this).getNativeArrayType(), null, FIELD_VALUE ) ); + fields.add( ((ArrayType)this).getNativeFieldName() ); break; case array_native: fields.add( new NamedStorageType( ((ArrayType)this).getArrayType(), null, null ) ); diff --git a/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java index ccbbcff..d35d893 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmArrayInstruction.java @@ -180,14 +180,6 @@ class WasmArrayInstruction extends WasmInstruction { if( functionName != null ) { // nonGC writer.writeFunctionCall( functionName, null ); } else { - switch( op ) { - case GET: - case SET: - case LEN: - writer.writeStructOperator( StructOperator.GET, arrayType, null, 2 ); // the native array is on position 2 (vtable, hashcode are before) - break; - default: - } writer.writeArrayOperator( op, arrayType ); } } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 4e1ca1b..4f0d385 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -735,9 +735,32 @@ public abstract class WasmCodeBuilder { * the line number in the Java source code */ protected void addArrayInstruction( ArrayOperator op, AnyType type, int javaCodePos, int lineNumber ) { + boolean useGC = options.useGC(); + if( useGC ) { + // replace the the array wrapper on the stack with the native array + int idx; + switch( op ) { + case GET: + idx = StackInspector.findInstructionThatPushValue( instructions, 1, javaCodePos ).idx; + break; + case SET: + idx = StackInspector.findInstructionThatPushValue( instructions, 2, javaCodePos ).idx; + break; + case LEN: + idx = instructions.size(); + break; + default: + idx = -1; + } + if( idx >= 0 ) { + ArrayType arrayType = types.arrayType( type ); + instructions.add( idx, new WasmStructInstruction( StructOperator.GET, arrayType, arrayType.getNativeFieldName(), javaCodePos, lineNumber, types ) ); + } + } + WasmArrayInstruction arrayInst = new WasmArrayInstruction( op, type, types, javaCodePos, lineNumber ); instructions.add( arrayInst ); - SyntheticFunctionName name = arrayInst.createNonGcFunction( options.useGC() ); + SyntheticFunctionName name = arrayInst.createNonGcFunction( useGC ); if( name != null ) { functions.markAsNeeded( name ); functions.markAsImport( name, name.getAnnotation() ); diff --git a/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java index 466da98..c81852a 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmStructInstruction.java @@ -66,9 +66,29 @@ class WasmStructInstruction extends WasmInstruction { * the type manager */ WasmStructInstruction( @Nonnull StructOperator op, @Nonnull String typeName, @Nullable NamedStorageType fieldName, int javaCodePos, int lineNumber, TypeManager types ) { + this( op, types.valueOf( typeName ), fieldName, javaCodePos, lineNumber, types ); + } + + /** + * Create an instance of numeric operation. + * + * @param op + * the struct operation + * @param type + * the type of the parameters + * @param fieldName + * the name of field if needed for the operation + * @param javaCodePos + * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code + * @param types + * the type manager + */ + WasmStructInstruction( @Nonnull StructOperator op, @Nonnull StructType type, @Nullable NamedStorageType fieldName, int javaCodePos, int lineNumber, TypeManager types ) { super( javaCodePos, lineNumber ); this.op = op; - this.type = types.valueOf( typeName ); + this.type = type; this.fieldName = fieldName; if( type != null && fieldName != null ) { type.useFieldName( fieldName ); diff --git a/src/de/inetsoftware/jwebassembly/wasm/ArrayType.java b/src/de/inetsoftware/jwebassembly/wasm/ArrayType.java index dc48d11..0c47728 100644 --- a/src/de/inetsoftware/jwebassembly/wasm/ArrayType.java +++ b/src/de/inetsoftware/jwebassembly/wasm/ArrayType.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 - 2020 Volker Berlin (i-net software) + * Copyright 2019 - 2021 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. @@ -35,6 +35,8 @@ public class ArrayType extends StructType { private AnyType nativeArrayType; + private NamedStorageType nativeFieldName; + private int componentClassIndex; /** @@ -59,6 +61,7 @@ public class ArrayType extends StructType { } else { this.nativeArrayType = arrayType; } + nativeFieldName = new NamedStorageType( this.nativeArrayType, getName(), TypeManager.FIELD_VALUE ); } /** @@ -126,10 +129,23 @@ public class ArrayType extends StructType { return arrayType; } + /** + * The native webassembly array type that we wrap + * @return the type + */ public AnyType getNativeArrayType() { return nativeArrayType; } + /** + * The native field name + * + * @return the field name + */ + public NamedStorageType getNativeFieldName() { + return nativeFieldName; + } + /** * {@inheritDoc} */