mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
more replacement for VarHandle
This commit is contained in:
parent
dbb49e99d1
commit
8cd3c5b9d5
@ -175,6 +175,7 @@ class FunctionManager {
|
|||||||
case UnsafeManager.UNSAFE_11:
|
case UnsafeManager.UNSAFE_11:
|
||||||
case UnsafeManager.FIELDUPDATER:
|
case UnsafeManager.FIELDUPDATER:
|
||||||
case UnsafeManager.VARHANDLE:
|
case UnsafeManager.VARHANDLE:
|
||||||
|
case UnsafeManager.METHOD_HANDLES:
|
||||||
// Unsafe method call will be replaces by the UnsafeManager
|
// Unsafe method call will be replaces by the UnsafeManager
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,8 @@ class UnsafeManager {
|
|||||||
/** VARHANDLE as modern replacement of Unsafe */
|
/** VARHANDLE as modern replacement of Unsafe */
|
||||||
static final String VARHANDLE = "java/lang/invoke/VarHandle";
|
static final String VARHANDLE = "java/lang/invoke/VarHandle";
|
||||||
|
|
||||||
|
static final String METHOD_HANDLES = "java/lang/invoke/MethodHandles$Lookup";
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final FunctionManager functions;
|
private final FunctionManager functions;
|
||||||
|
|
||||||
@ -137,6 +139,7 @@ class UnsafeManager {
|
|||||||
patch( instructions, i, callInst );
|
patch( instructions, i, callInst );
|
||||||
break;
|
break;
|
||||||
case VARHANDLE:
|
case VARHANDLE:
|
||||||
|
case METHOD_HANDLES:
|
||||||
patchVarHandle( instructions, i, callInst );
|
patchVarHandle( instructions, i, callInst );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -746,7 +749,7 @@ class UnsafeManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch an unsafe function that access a field
|
* Remove an unsafe function that access a field
|
||||||
*
|
*
|
||||||
* @param instructions
|
* @param instructions
|
||||||
* the instruction list
|
* the instruction list
|
||||||
@ -754,6 +757,8 @@ class UnsafeManager {
|
|||||||
* the index in the instructions
|
* the index in the instructions
|
||||||
* @param callInst
|
* @param callInst
|
||||||
* the method call to Unsafe
|
* the method call to Unsafe
|
||||||
|
* @param paramCount
|
||||||
|
* the count of params that must be removed from stack (including THIS if instance method)
|
||||||
*/
|
*/
|
||||||
private void remove( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst, int paramCount ) {
|
private void remove( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst, int paramCount ) {
|
||||||
int from = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), paramCount, callInst.getCodePosition() ).idx;
|
int from = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), paramCount, callInst.getCodePosition() ).idx;
|
||||||
@ -778,15 +783,70 @@ class UnsafeManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void patchVarHandle( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) {
|
private void patchVarHandle( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) throws IOException {
|
||||||
FunctionName name = callInst.getFunctionName();
|
FunctionName name = callInst.getFunctionName();
|
||||||
switch( name.methodName ) {
|
switch( name.methodName ) {
|
||||||
case "getAndSet":
|
case "findVarHandle":
|
||||||
patchVarHandleFieldFunction( instructions, idx, callInst, name, 3 );
|
patch_findVarHandle( instructions, idx, callInst );
|
||||||
break;
|
break;
|
||||||
|
case "arrayElementVarHandle": // java/lang/invoke/MethodHandles
|
||||||
|
UnsafeState state = findUnsafeState( instructions, idx );
|
||||||
|
int from = StackInspector.findInstructionThatPushValue( instructions, 2, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
|
StackValue stackValue = StackInspector.findInstructionThatPushValue( instructions, 1, callInst.getCodePosition() );
|
||||||
|
state.typeName = getClassConst( instructions, stackValue );
|
||||||
|
break;
|
||||||
|
case "getAndSet":
|
||||||
|
case "set":
|
||||||
|
case "getAcquire":
|
||||||
|
case "getAndAdd":
|
||||||
|
case "getAndBitwiseOr":
|
||||||
|
case "get":
|
||||||
|
case "compareAndSet":
|
||||||
|
case "weakCompareAndSet":
|
||||||
|
case "setVolatile":
|
||||||
|
case "setRelease":
|
||||||
|
case "setOpaque":
|
||||||
|
patchVarHandleFieldFunction( instructions, idx, callInst, name, callInst.getPopCount() );
|
||||||
|
break;
|
||||||
|
case "releaseFence":
|
||||||
|
nop( instructions, idx, idx + 1 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new WasmException( "Unsupported VarHandle method: " + name.signatureName, -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch a method call to Unsafe.objectFieldOffset() and find the parameter for other patch operations.
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list
|
||||||
|
* @param idx
|
||||||
|
* the index in the instructions
|
||||||
|
* @param callInst
|
||||||
|
* the method call to Unsafe
|
||||||
|
* @throws IOException
|
||||||
|
* If any I/O error occur
|
||||||
|
*/
|
||||||
|
private void patch_findVarHandle( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) throws IOException {
|
||||||
|
UnsafeState state = findUnsafeState( instructions, idx );
|
||||||
|
|
||||||
|
// objectFieldOffset() has 3 parameters THIS(Unsafe), class and the fieldname
|
||||||
|
List<WasmInstruction> paramInstructions = instructions.subList( 0, idx );
|
||||||
|
int from = StackInspector.findInstructionThatPushValue( paramInstructions, 4, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
|
StackValue stackValue = StackInspector.findInstructionThatPushValue( paramInstructions, 2, callInst.getCodePosition() );
|
||||||
|
state.fieldName = ((WasmConstStringInstruction)stackValue.instr).getValue();
|
||||||
|
|
||||||
|
// find the class value on which getDeclaredField is called
|
||||||
|
stackValue = StackInspector.findInstructionThatPushValue( paramInstructions, 3, callInst.getCodePosition() );
|
||||||
|
state.typeName = getClassConst( instructions, stackValue );
|
||||||
|
|
||||||
|
useFieldName( state );
|
||||||
|
nop( instructions, from, idx + 2 );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch an unsafe function that access a field
|
* Patch an unsafe function that access a field
|
||||||
*
|
*
|
||||||
@ -815,6 +875,26 @@ class UnsafeManager {
|
|||||||
}
|
}
|
||||||
AnyType[] paramTypes = callInst.getPopValueTypes();
|
AnyType[] paramTypes = callInst.getPopValueTypes();
|
||||||
switch( name.methodName ) {
|
switch( name.methodName ) {
|
||||||
|
case "compareAndSet":
|
||||||
|
case "weakCompareAndSet":
|
||||||
|
AnyType type = paramTypes[3];
|
||||||
|
if( type.isRefType() ) {
|
||||||
|
type = ValueType.ref;
|
||||||
|
}
|
||||||
|
return "local.get 1" // THIS
|
||||||
|
+ " struct.get " + state.typeName + ' ' + state.fieldName //
|
||||||
|
+ " local.get 2 " // expected
|
||||||
|
+ " " + type + ".eq" //
|
||||||
|
+ " if" //
|
||||||
|
+ " local.get 1" // THIS
|
||||||
|
+ " local.get 3 " // update
|
||||||
|
+ " struct.set " + state.typeName + ' ' + state.fieldName //
|
||||||
|
+ " i32.const 1" //
|
||||||
|
+ " return" //
|
||||||
|
+ " end" //
|
||||||
|
+ " i32.const 1" //
|
||||||
|
+ " return";
|
||||||
|
|
||||||
case "getAndSet":
|
case "getAndSet":
|
||||||
return "local.get 1" // THIS
|
return "local.get 1" // THIS
|
||||||
+ " struct.get " + state.typeName + ' ' + state.fieldName //
|
+ " struct.get " + state.typeName + ' ' + state.fieldName //
|
||||||
@ -823,6 +903,10 @@ class UnsafeManager {
|
|||||||
+ " struct.set " + state.typeName + ' ' + state.fieldName //
|
+ " struct.set " + state.typeName + ' ' + state.fieldName //
|
||||||
+ " return";
|
+ " return";
|
||||||
|
|
||||||
|
case "set":
|
||||||
|
return "local.get 1" // THIS
|
||||||
|
+ " local.get 2" // x
|
||||||
|
+ " struct.set " + state.typeName + ' ' + state.fieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new RuntimeException( name.signatureName );
|
throw new RuntimeException( name.signatureName );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user