fix the order of parameters on the stack for array.get/set

This commit is contained in:
Volker Berlin 2021-01-02 20:48:29 +01:00
parent 762d7d2f6c
commit 6bd993617c
5 changed files with 67 additions and 14 deletions

View File

@ -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<String> 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 ) );

View File

@ -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 );
}
}

View File

@ -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() );

View File

@ -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 );

View File

@ -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}
*/