fix Unsafe for array elements

This commit is contained in:
Volker Berlin 2023-02-28 20:33:22 +01:00
parent 60d8340760
commit 16d04beeff
No known key found for this signature in database
GPG Key ID: 988423EF815BE4CB

View File

@ -513,7 +513,7 @@ class UnsafeManager {
} }
WatCodeSyntheticFunctionName func = WatCodeSyntheticFunctionName func =
new WatCodeSyntheticFunctionName( fieldNameWithOffset.className, '.' + name.methodName, name.signature, "", (AnyType[])null ) { new WatCodeSyntheticFunctionName( fieldNameWithOffset.className, '.' + fieldNameWithOffset.methodName + '.' + name.methodName, name.signature, "", (AnyType[])null ) {
@Override @Override
protected String getCode() { protected String getCode() {
UnsafeState state = null; UnsafeState state = null;
@ -525,7 +525,7 @@ class UnsafeManager {
} }
if( state == null ) { if( state == null ) {
if( functions.isFinish() ) { if( functions.isFinish() ) {
throw new RuntimeException( name.signatureName ); throw new RuntimeException( this.fullName + name.signature );
} }
// we are in the scan phase. The static code was not scanned yet. // we are in the scan phase. The static code was not scanned yet.
return ""; return "";
@ -540,6 +540,8 @@ class UnsafeManager {
if( type.isRefType() ) { if( type.isRefType() ) {
type = ValueType.ref; type = ValueType.ref;
} }
if( state.fieldName != null ) {
// field access
int paramOffset = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater".equals( name.className ) ? -1 : 0; int paramOffset = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater".equals( name.className ) ? -1 : 0;
return "local.get 1" // THIS return "local.get 1" // THIS
+ " struct.get " + state.typeName + ' ' + state.fieldName // + " struct.get " + state.typeName + ' ' + state.fieldName //
@ -554,6 +556,26 @@ class UnsafeManager {
+ " end" // + " end" //
+ " i32.const 1" // + " i32.const 1" //
+ " return"; + " return";
} else {
// array access
return "local.get 1" // THIS
+ " local.get 2" // the array index
+ " i32.wrap_i64" // long -> int
+ " array.get " + state.typeName //
+ " local.get 3 " // expected
+ " " + type + ".eq" //
+ " if" //
+ " local.get 1" // THIS
+ " local.get 2" // the array index
+ " i32.wrap_i64" // long -> int
+ " local.get 4 " // update
+ " array.set " + state.typeName //
+ " i32.const 1" //
+ " return" //
+ " end" //
+ " i32.const 1" //
+ " return";
}
case "getAndAddInt": case "getAndAddInt":
case "getAndAddLong": case "getAndAddLong":
@ -584,9 +606,19 @@ class UnsafeManager {
case "putOrderedObject": case "putOrderedObject":
case "putObjectVolatile": case "putObjectVolatile":
case "putObject": case "putObject":
if( state.fieldName != null ) {
// field access
return "local.get 1" // THIS return "local.get 1" // THIS
+ " local.get 3" // x + " local.get 3" // x
+ " struct.set " + state.typeName + ' ' + state.fieldName; + " struct.set " + state.typeName + ' ' + state.fieldName;
} else {
// array access
return "local.get 1" // THIS
+ " local.get 2" // the array index
+ " i32.wrap_i64" // long -> int
+ " local.get 3" // x
+ " array.set " + state.typeName;
}
case "getInt": case "getInt":
case "getLong": case "getLong":
@ -597,6 +629,7 @@ class UnsafeManager {
case "getObjectVolatile": case "getObjectVolatile":
return "local.get 1" // array return "local.get 1" // array
+ " local.get 2" // the array index + " local.get 2" // the array index
+ " i32.wrap_i64" // long -> int
+ " array.get " + state.typeName + " array.get " + state.typeName
+ " return"; + " return";
} }
@ -604,8 +637,9 @@ class UnsafeManager {
throw new RuntimeException( name.signatureName ); throw new RuntimeException( name.signatureName );
} }
}; };
functions.markAsNeeded( func, true ); // original function has an THIS parameter of the Unsafe instance, we need to consume it boolean needThisParameter = true;
WasmCallInstruction call = new WasmCallInstruction( func, callInst.getCodePosition(), callInst.getLineNumber(), callInst.getTypeManager(), false ); functions.markAsNeeded( func, needThisParameter ); // original function has an THIS parameter of the Unsafe instance, we need to consume it
WasmCallInstruction call = new WasmCallInstruction( func, callInst.getCodePosition(), callInst.getLineNumber(), callInst.getTypeManager(), needThisParameter );
instructions.set( idx, call ); instructions.set( idx, call );
// a virtual method call has also a DUP of this because we need for virtual method dispatch the parameter 2 times. // a virtual method call has also a DUP of this because we need for virtual method dispatch the parameter 2 times.