mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 23:47:51 +01:00
fix Unsafe for array elements
This commit is contained in:
parent
60d8340760
commit
16d04beeff
@ -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,20 +540,42 @@ class UnsafeManager {
|
|||||||
if( type.isRefType() ) {
|
if( type.isRefType() ) {
|
||||||
type = ValueType.ref;
|
type = ValueType.ref;
|
||||||
}
|
}
|
||||||
int paramOffset = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater".equals( name.className ) ? -1 : 0;
|
if( state.fieldName != null ) {
|
||||||
return "local.get 1" // THIS
|
// field access
|
||||||
+ " struct.get " + state.typeName + ' ' + state.fieldName //
|
int paramOffset = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater".equals( name.className ) ? -1 : 0;
|
||||||
+ " local.get " + (3 + paramOffset) // expected
|
return "local.get 1" // THIS
|
||||||
+ " " + type + ".eq" //
|
+ " struct.get " + state.typeName + ' ' + state.fieldName //
|
||||||
+ " if" //
|
+ " local.get " + (3 + paramOffset) // expected
|
||||||
+ " local.get 1" // THIS
|
+ " " + type + ".eq" //
|
||||||
+ " local.get " + (4 + paramOffset) // update
|
+ " if" //
|
||||||
+ " struct.set " + state.typeName + ' ' + state.fieldName //
|
+ " local.get 1" // THIS
|
||||||
+ " i32.const 1" //
|
+ " local.get " + (4 + paramOffset) // update
|
||||||
+ " return" //
|
+ " struct.set " + state.typeName + ' ' + state.fieldName //
|
||||||
+ " end" //
|
+ " i32.const 1" //
|
||||||
+ " i32.const 1" //
|
+ " return" //
|
||||||
+ " return";
|
+ " end" //
|
||||||
|
+ " i32.const 1" //
|
||||||
|
+ " 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":
|
||||||
return "local.get 1" // THIS
|
if( state.fieldName != null ) {
|
||||||
+ " local.get 3" // x
|
// field access
|
||||||
+ " struct.set " + state.typeName + ' ' + state.fieldName;
|
return "local.get 1" // THIS
|
||||||
|
+ " local.get 3" // x
|
||||||
|
+ " 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.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user