mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
Some Unsafe stuff for Java 11
This commit is contained in:
parent
86004bfb4c
commit
577d2883c9
@ -170,9 +170,11 @@ class FunctionManager {
|
|||||||
FunctionName markAsNeeded( @Nonnull FunctionName name, boolean needThisParameter ) {
|
FunctionName markAsNeeded( @Nonnull FunctionName name, boolean needThisParameter ) {
|
||||||
FunctionState state = getOrCreate( name );
|
FunctionState state = getOrCreate( name );
|
||||||
if( state.state == State.None ) {
|
if( state.state == State.None ) {
|
||||||
if( "sun/misc/Unsafe".equals( name.className ) ) {
|
switch( name.className ) {
|
||||||
// Unsafe method call will be replaces by the UnsafeManager
|
case UnsafeManager.UNSAFE_8:
|
||||||
return name;
|
case UnsafeManager.UNSAFE_11:
|
||||||
|
// Unsafe method call will be replaces by the UnsafeManager
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
if( isFinish ) {
|
if( isFinish ) {
|
||||||
throw new WasmException( "Prepare was already finish: " + name.signatureName, -1 );
|
throw new WasmException( "Prepare was already finish: " + name.signatureName, -1 );
|
||||||
|
@ -65,10 +65,16 @@ import de.inetsoftware.jwebassembly.wasm.VariableOperator;
|
|||||||
*/
|
*/
|
||||||
class UnsafeManager {
|
class UnsafeManager {
|
||||||
|
|
||||||
|
/** Unsafe class bane in Java 8 */
|
||||||
|
static final String UNSAFE_8 = "sun/misc/Unsafe";
|
||||||
|
|
||||||
|
/** Unsafe class bane in Java 11 */
|
||||||
|
static final String UNSAFE_11 = "jdk/internal/misc/Unsafe";
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
private final FunctionManager functions;
|
private final FunctionManager functions;
|
||||||
|
|
||||||
private final HashMap<FunctionName, UnsafeState> unsafes = new HashMap<>();
|
private final HashMap<FunctionName, UnsafeState> unsafes = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of the manager
|
* Create an instance of the manager
|
||||||
@ -94,8 +100,11 @@ class UnsafeManager {
|
|||||||
case CallVirtual:
|
case CallVirtual:
|
||||||
case Call:
|
case Call:
|
||||||
WasmCallInstruction callInst = (WasmCallInstruction)instr;
|
WasmCallInstruction callInst = (WasmCallInstruction)instr;
|
||||||
if( "sun/misc/Unsafe".equals( callInst.getFunctionName().className ) ) {
|
switch( callInst.getFunctionName().className ) {
|
||||||
patch( instructions, i, callInst );
|
case UNSAFE_8:
|
||||||
|
case UNSAFE_11:
|
||||||
|
patch( instructions, i, callInst );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -117,18 +126,45 @@ class UnsafeManager {
|
|||||||
FunctionName name = callInst.getFunctionName();
|
FunctionName name = callInst.getFunctionName();
|
||||||
switch( name.signatureName ) {
|
switch( name.signatureName ) {
|
||||||
case "sun/misc/Unsafe.getUnsafe()Lsun/misc/Unsafe;":
|
case "sun/misc/Unsafe.getUnsafe()Lsun/misc/Unsafe;":
|
||||||
|
case "jdk/internal/misc/Unsafe.getUnsafe()Ljdk/internal/misc/Unsafe;":
|
||||||
patch_getUnsafe( instructions, idx );
|
patch_getUnsafe( instructions, idx );
|
||||||
break;
|
break;
|
||||||
case "sun/misc/Unsafe.objectFieldOffset(Ljava/lang/reflect/Field;)J":
|
case "sun/misc/Unsafe.objectFieldOffset(Ljava/lang/reflect/Field;)J":
|
||||||
patch_objectFieldOffset( instructions, idx, callInst );
|
patch_objectFieldOffset_Java8( instructions, idx, callInst );
|
||||||
|
break;
|
||||||
|
case "jdk/internal/misc/Unsafe.objectFieldOffset(Ljava/lang/Class;Ljava/lang/String;)J":
|
||||||
|
patch_objectFieldOffset_Java11( instructions, idx, callInst );
|
||||||
|
break;
|
||||||
|
case "sun/misc/Unsafe.arrayBaseOffset(Ljava/lang/Class;)I":
|
||||||
|
case "jdk/internal/misc/Unsafe.arrayBaseOffset(Ljava/lang/Class;)I":
|
||||||
|
patch_arrayBaseOffset( instructions, idx, callInst );
|
||||||
|
break;
|
||||||
|
case "sun/misc/Unsafe.arrayIndexScale(Ljava/lang/Class;)I":
|
||||||
|
case "jdk/internal/misc/Unsafe.arrayIndexScale(Ljava/lang/Class;)I":
|
||||||
|
patch_arrayIndexScale( instructions, idx, callInst );
|
||||||
break;
|
break;
|
||||||
case "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I":
|
case "sun/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I":
|
||||||
case "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I":
|
case "sun/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I":
|
||||||
case "sun/misc/Unsafe.putOrderedInt(Ljava/lang/Object;JI)V":
|
case "sun/misc/Unsafe.putOrderedInt(Ljava/lang/Object;JI)V":
|
||||||
patchFunction( instructions, idx, callInst, name, 2 );
|
case "sun/misc/Unsafe.getObjectVolatile(Ljava/lang/Object;J)Ljava/lang/Object;":
|
||||||
|
case "jdk/internal/misc/Unsafe.getAndAddInt(Ljava/lang/Object;JI)I":
|
||||||
|
case "jdk/internal/misc/Unsafe.getAndSetInt(Ljava/lang/Object;JI)I":
|
||||||
|
case "jdk/internal/misc/Unsafe.putIntRelease(Ljava/lang/Object;JI)V":
|
||||||
|
patchFieldFunction( instructions, idx, callInst, name, 2 );
|
||||||
break;
|
break;
|
||||||
case "sun/misc/Unsafe.compareAndSwapInt(Ljava/lang/Object;JII)Z":
|
case "sun/misc/Unsafe.compareAndSwapInt(Ljava/lang/Object;JII)Z":
|
||||||
patchFunction( instructions, idx, callInst, name, 3 );
|
case "jdk/internal/misc/Unsafe.compareAndSetInt(Ljava/lang/Object;JII)Z":
|
||||||
|
patchFieldFunction( instructions, idx, callInst, name, 3 );
|
||||||
|
break;
|
||||||
|
case "jdk/internal/misc/Unsafe.getLongUnaligned(Ljava/lang/Object;J)J":
|
||||||
|
case "jdk/internal/misc/Unsafe.getIntUnaligned(Ljava/lang/Object;J)I":
|
||||||
|
patch_getLongUnaligned( instructions, idx, callInst, name );
|
||||||
|
break;
|
||||||
|
case "jdk/internal/misc/Unsafe.isBigEndian()Z":
|
||||||
|
patch_isBigEndian( instructions, idx, callInst );
|
||||||
|
break;
|
||||||
|
case "jdk/internal/misc/Unsafe.storeFence()V":
|
||||||
|
remove( instructions, idx, callInst );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new WasmException( "Unsupported Unsafe method: " + name.signatureName, -1 );
|
throw new WasmException( "Unsupported Unsafe method: " + name.signatureName, -1 );
|
||||||
@ -146,10 +182,77 @@ class UnsafeManager {
|
|||||||
private void patch_getUnsafe( List<WasmInstruction> instructions, int idx ) {
|
private void patch_getUnsafe( List<WasmInstruction> instructions, int idx ) {
|
||||||
WasmInstruction instr = instructions.get( idx + 1 );
|
WasmInstruction instr = instructions.get( idx + 1 );
|
||||||
|
|
||||||
FunctionName fieldName = ((WasmGlobalInstruction)instr).getFieldName();
|
int to = idx + (instr.getType() == Type.Global ? 2 : 1);
|
||||||
unsafes.putIfAbsent( fieldName, new UnsafeState() );
|
|
||||||
|
|
||||||
nop( instructions, idx, idx + 2 );
|
nop( instructions, idx, to );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the field on which the offset is assign: long FIELD_OFFSET = UNSAFE.objectFieldOffset(...
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list of a function/method
|
||||||
|
* @param idx
|
||||||
|
* the index in the instructions
|
||||||
|
* @return the state
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
private UnsafeState findUnsafeState( List<WasmInstruction> instructions, int idx ) {
|
||||||
|
// find the field on which the offset is assign: long FIELD_OFFSET = UNSAFE.objectFieldOffset(...
|
||||||
|
WasmInstruction instr;
|
||||||
|
INSTR: do {
|
||||||
|
instr = instructions.get( idx + 1 );
|
||||||
|
switch( instr.getType() ) {
|
||||||
|
case Convert:
|
||||||
|
idx++;
|
||||||
|
continue INSTR;
|
||||||
|
case Global:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new WasmException( "Unsupported assign operation for Unsafe filed offsetd: " + instr.getType(), -1 );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} while( true );
|
||||||
|
FunctionName fieldNameWithOffset = ((WasmGlobalInstruction)instr).getFieldName();
|
||||||
|
UnsafeState state = unsafes.get( fieldNameWithOffset );
|
||||||
|
if( state == null ) {
|
||||||
|
unsafes.put( fieldNameWithOffset, state = new UnsafeState() );
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class name from the stack value. It is searching a WasmConstClassInstruction that produce the value of
|
||||||
|
* the stack value.
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list of a function/method
|
||||||
|
* @param stackValue
|
||||||
|
* the stack value (instruction and position that produce an stack value)
|
||||||
|
* @return the class name like: java/lang/String
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
private static String getClassConst( List<WasmInstruction> instructions, StackValue stackValue ) {
|
||||||
|
WasmInstruction instr = stackValue.instr;
|
||||||
|
switch( instr.getType() ) {
|
||||||
|
case Local:
|
||||||
|
int slot = ((WasmLocalInstruction)instr).getSlot();
|
||||||
|
for( int i = stackValue.idx - 1; i >= 0; i-- ) {
|
||||||
|
instr = instructions.get( i );
|
||||||
|
if( instr.getType() == Type.Local ) {
|
||||||
|
WasmLocalInstruction loadInstr = (WasmLocalInstruction)instr;
|
||||||
|
if( loadInstr.getSlot() == slot && loadInstr.getOperator() == VariableOperator.set ) {
|
||||||
|
stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, i ), 1, instr.getCodePosition() );
|
||||||
|
instr = stackValue.instr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
return ((WasmConstClassInstruction)instr).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,20 +265,15 @@ class UnsafeManager {
|
|||||||
* @param callInst
|
* @param callInst
|
||||||
* the method call to Unsafe
|
* the method call to Unsafe
|
||||||
*/
|
*/
|
||||||
private void patch_objectFieldOffset( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) {
|
private void patch_objectFieldOffset_Java8( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) {
|
||||||
// find the field on which the offset is assign: long FIELD_OFFSET = UNSAFE.objectFieldOffset(...
|
UnsafeState state = findUnsafeState( instructions, idx );
|
||||||
WasmInstruction instr = instructions.get( idx + 1 );
|
|
||||||
FunctionName fieldNameWithOffset = ((WasmGlobalInstruction)instr).getFieldName();
|
|
||||||
UnsafeState state = unsafes.get( fieldNameWithOffset );
|
|
||||||
if( state == null ) {
|
|
||||||
unsafes.put( fieldNameWithOffset, state = new UnsafeState() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// objectFieldOffset() has 2 parameters THIS(Unsafe) and a Field
|
// objectFieldOffset() has 2 parameters THIS(Unsafe) and a Field
|
||||||
int from = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), 2, callInst.getCodePosition() ).idx;
|
List<WasmInstruction> paramInstructions = instructions.subList( 0, idx );
|
||||||
|
int from = StackInspector.findInstructionThatPushValue( paramInstructions, 2, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
StackValue stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), 1, callInst.getCodePosition() );
|
StackValue stackValue = StackInspector.findInstructionThatPushValue( paramInstructions, 1, callInst.getCodePosition() );
|
||||||
instr = stackValue.instr;
|
WasmInstruction instr = stackValue.instr;
|
||||||
WasmCallInstruction fieldInst = (WasmCallInstruction)instr;
|
WasmCallInstruction fieldInst = (WasmCallInstruction)instr;
|
||||||
|
|
||||||
FunctionName fieldFuncName = fieldInst.getFunctionName();
|
FunctionName fieldFuncName = fieldInst.getFunctionName();
|
||||||
@ -186,24 +284,7 @@ class UnsafeManager {
|
|||||||
|
|
||||||
// find the class value on which getDeclaredField is called
|
// find the class value on which getDeclaredField is called
|
||||||
stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, stackValue.idx ), 1, fieldInst.getCodePosition() );
|
stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, stackValue.idx ), 1, fieldInst.getCodePosition() );
|
||||||
instr = stackValue.instr;
|
state.typeName = getClassConst( instructions, stackValue );
|
||||||
switch( instr.getType() ) {
|
|
||||||
case Local:
|
|
||||||
int slot = ((WasmLocalInstruction)instr).getSlot();
|
|
||||||
for( int i = stackValue.idx - 1; i >= 0; i-- ) {
|
|
||||||
instr = instructions.get( i );
|
|
||||||
if( instr.getType() == Type.Local ) {
|
|
||||||
WasmLocalInstruction loadInstr = (WasmLocalInstruction)instr;
|
|
||||||
if( loadInstr.getSlot() == slot && loadInstr.getOperator() == VariableOperator.set ) {
|
|
||||||
stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, i ), 1, fieldInst.getCodePosition() );
|
|
||||||
instr = stackValue.instr;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
state.typeName = ((WasmConstClassInstruction)instr).getValue();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -213,6 +294,76 @@ class UnsafeManager {
|
|||||||
nop( instructions, from, idx + 2 );
|
nop( instructions, from, idx + 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
private void patch_objectFieldOffset_Java11( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) {
|
||||||
|
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, 3, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
|
StackValue stackValue = StackInspector.findInstructionThatPushValue( paramInstructions, 1, callInst.getCodePosition() );
|
||||||
|
state.fieldName = ((WasmConstStringInstruction)stackValue.instr).getValue();
|
||||||
|
|
||||||
|
// find the class value on which getDeclaredField is called
|
||||||
|
stackValue = StackInspector.findInstructionThatPushValue( paramInstructions, 2, callInst.getCodePosition() );
|
||||||
|
state.typeName = getClassConst( instructions, stackValue );
|
||||||
|
|
||||||
|
nop( instructions, from, idx + 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch a method call to Unsafe.arrayBaseOffset() 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
|
||||||
|
*/
|
||||||
|
private void patch_arrayBaseOffset( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) {
|
||||||
|
UnsafeState state = findUnsafeState( instructions, idx );
|
||||||
|
|
||||||
|
// objectFieldOffset() has 2 parameters THIS(Unsafe) and a Class from an array
|
||||||
|
List<WasmInstruction> paramInstructions = instructions.subList( 0, idx );
|
||||||
|
int from = StackInspector.findInstructionThatPushValue( paramInstructions, 2, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
|
StackValue stackValue = StackInspector.findInstructionThatPushValue( paramInstructions, 1, callInst.getCodePosition() );
|
||||||
|
state.typeName = getClassConst( instructions, stackValue );
|
||||||
|
|
||||||
|
nop( instructions, from, idx );
|
||||||
|
// we put the constant value 0 on the stack, we does not need array base offset in WASM
|
||||||
|
instructions.set( idx, new WasmConstNumberInstruction( 0, callInst.getCodePosition(), callInst.getLineNumber() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch method call to Unsafe.arrayIndexScale()
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list
|
||||||
|
* @param idx
|
||||||
|
* the index in the instructions
|
||||||
|
* @param callInst
|
||||||
|
* the method call to Unsafe
|
||||||
|
*/
|
||||||
|
private void patch_arrayIndexScale( List<WasmInstruction> instructions, int idx, WasmCallInstruction callInst ) {
|
||||||
|
int from = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), 2, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
|
nop( instructions, from, idx );
|
||||||
|
// we put the constant value 1 on the stack because we does not want shift array positions
|
||||||
|
instructions.set( idx, new WasmConstNumberInstruction( 1, callInst.getCodePosition(), callInst.getLineNumber() ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch an unsafe function that access a field
|
* Patch an unsafe function that access a field
|
||||||
*
|
*
|
||||||
@ -228,7 +379,7 @@ class UnsafeManager {
|
|||||||
* the function parameter with the field offset. This must be a long (Java signature "J"). The THIS
|
* the function parameter with the field offset. This must be a long (Java signature "J"). The THIS
|
||||||
* parameter has the index 0.
|
* parameter has the index 0.
|
||||||
*/
|
*/
|
||||||
private void patchFunction( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst, FunctionName name, int fieldNameParam ) {
|
private void patchFieldFunction( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst, FunctionName name, int fieldNameParam ) {
|
||||||
StackValue stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), fieldNameParam, callInst.getCodePosition() );
|
StackValue stackValue = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), fieldNameParam, callInst.getCodePosition() );
|
||||||
FunctionName fieldNameWithOffset = ((WasmGlobalInstruction)stackValue.instr).getFieldName();
|
FunctionName fieldNameWithOffset = ((WasmGlobalInstruction)stackValue.instr).getFieldName();
|
||||||
WatCodeSyntheticFunctionName func =
|
WatCodeSyntheticFunctionName func =
|
||||||
@ -298,6 +449,58 @@ class UnsafeManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch an unsafe function that access a field
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list
|
||||||
|
* @param idx
|
||||||
|
* the index in the instructions
|
||||||
|
* @param callInst
|
||||||
|
* the method call to Unsafe
|
||||||
|
*/
|
||||||
|
private void patch_getLongUnaligned( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst, FunctionName name ) {
|
||||||
|
WatCodeSyntheticFunctionName func = new WatCodeSyntheticFunctionName( "", name.methodName, name.signature, "unreachable", (AnyType[])null );
|
||||||
|
functions.markAsNeeded( func, false );
|
||||||
|
WasmCallInstruction call = new WasmCallInstruction( func, callInst.getCodePosition(), callInst.getLineNumber(), callInst.getTypeManager(), false );
|
||||||
|
instructions.set( idx, call );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch an unsafe function that access a field
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list
|
||||||
|
* @param idx
|
||||||
|
* the index in the instructions
|
||||||
|
* @param callInst
|
||||||
|
* the method call to Unsafe
|
||||||
|
*/
|
||||||
|
private void patch_isBigEndian( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst ) {
|
||||||
|
// int from = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), 1, callInst.getCodePosition() ).idx;
|
||||||
|
//
|
||||||
|
// nop( instructions, from, idx );
|
||||||
|
|
||||||
|
// on x86 use little endian
|
||||||
|
instructions.set( idx, new WasmConstNumberInstruction( 0, callInst.getCodePosition(), callInst.getLineNumber() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Patch an unsafe function that access a field
|
||||||
|
*
|
||||||
|
* @param instructions
|
||||||
|
* the instruction list
|
||||||
|
* @param idx
|
||||||
|
* the index in the instructions
|
||||||
|
* @param callInst
|
||||||
|
* the method call to Unsafe
|
||||||
|
*/
|
||||||
|
private void remove( List<WasmInstruction> instructions, int idx, final WasmCallInstruction callInst ) {
|
||||||
|
int from = StackInspector.findInstructionThatPushValue( instructions.subList( 0, idx ), 1, callInst.getCodePosition() ).idx;
|
||||||
|
|
||||||
|
nop( instructions, from, idx + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace the instructions with NOP operations
|
* Replace the instructions with NOP operations
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user