Skip to content

Commit

Permalink
Fix relationship between VM method and static native methods
Browse files Browse the repository at this point in the history
  • Loading branch information
rakachan committed Sep 8, 2021
1 parent 224318d commit 454b263
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ public final class NativeEnvProcessor extends EspressoProcessor {

private static final String GENERATE_INTRISIFICATION = "com.oracle.truffle.espresso.substitutions.GenerateNativeEnv";

private static final String SHOULD_NOT_REACH_HERE = "com.oracle.truffle.espresso.meta.EspressoError.shouldNotReachHere()";

protected static final String IMPORT_NATIVE_SIGNATURE = NATIVE_SIGNATURE;
protected static final String IMPORT_NATIVE_TYPE = NATIVE_TYPE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2089,7 +2089,7 @@ private Substitutions.EspressoRootNodeFactory lookupKnownVmMethods(@Pointer Truf
try {
long functionPointer = InteropLibrary.getUncached().asPointer(closure);
CallableFromNative.Factory knownVmMethod = getVM().lookupKnownVmMethod(functionPointer);
if (knownVmMethod != null) {
if (knownVmMethod != null && IntrinsifiedNativeMethodNode.validParameterCount(knownVmMethod, targetMethod)) {
return createJniRootNodeFactory(() -> new IntrinsifiedNativeMethodNode(knownVmMethod, targetMethod, getVM()), targetMethod);
}
} catch (UnsupportedMessageException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,27 @@
public class IntrinsifiedNativeMethodNode extends EspressoMethodNode {
@Child private CallableFromNative nativeMethod;
private final Object env;
private final boolean prependClass;

public IntrinsifiedNativeMethodNode(CallableFromNative.Factory factory, Method method, Object env) {
super(method.getMethodVersion());
this.nativeMethod = insert(factory.create(getMeta()));
this.env = env;
this.prependClass = shouldPrependClass(factory, method);
}

@Override
Object executeBody(VirtualFrame frame) {
return nativeMethod.invokeDirect(env, frame.getArguments());
Object[] args = frame.getArguments();
if (prependClass) {
Method method = getMethod();
int parameterCount = method.getParameterCount();
Object[] newArgs = new Object[parameterCount + 1];
newArgs[0] = method.getDeclaringKlass().mirror();
System.arraycopy(args, 0, newArgs, 1, parameterCount);
args = newArgs;
}
return nativeMethod.invokeDirect(env, args);
}

@Override
Expand All @@ -52,4 +63,13 @@ void initializeBody(VirtualFrame frame) {
public int getBci(Frame frame) {
return -2;
}

/* Static native methods may prepend the Class in the arg array */
private static boolean shouldPrependClass(CallableFromNative.Factory factory, Method method) {
return method.isStatic() && (factory.parameterCount()) == method.getParameterCount() + 1;
}

public static boolean validParameterCount(CallableFromNative.Factory factory, Method method) {
return factory.parameterCount() == method.getParameterCount() || shouldPrependClass(factory, method);
}
}

0 comments on commit 454b263

Please sign in to comment.