diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/constantpool/Resolution.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/constantpool/Resolution.java
index 239052f3c1ca..c96eaaa59eb0 100644
--- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/constantpool/Resolution.java
+++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/constantpool/Resolution.java
@@ -22,29 +22,15 @@
*/
package com.oracle.truffle.espresso.constantpool;
+import java.util.logging.Level;
+
import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.espresso.EspressoLanguage;
import com.oracle.truffle.espresso.EspressoOptions;
-import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
-import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
-import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Descriptor;
-import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
-import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
-import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
-import com.oracle.truffle.espresso.impl.ClassRegistry;
-import com.oracle.truffle.espresso.impl.Field;
-import com.oracle.truffle.espresso.impl.Klass;
-import com.oracle.truffle.espresso.impl.Member;
-import com.oracle.truffle.espresso.impl.Method;
-import com.oracle.truffle.espresso.impl.ObjectKlass;
-import com.oracle.truffle.espresso.meta.Meta;
-import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode;
-import com.oracle.truffle.espresso.nodes.methodhandle.MHLinkToNode;
import com.oracle.truffle.espresso.classfile.ConstantPool.Tag;
-import com.oracle.truffle.espresso.meta.EspressoError;
import com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute;
import com.oracle.truffle.espresso.classfile.constantpool.ClassConstant;
import com.oracle.truffle.espresso.classfile.constantpool.ClassMethodRefConstant;
@@ -58,7 +44,23 @@
import com.oracle.truffle.espresso.classfile.constantpool.MethodTypeConstant;
import com.oracle.truffle.espresso.classfile.constantpool.Resolvable;
import com.oracle.truffle.espresso.classfile.constantpool.StringConstant;
+import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
+import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
+import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Descriptor;
+import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
+import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
+import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
import com.oracle.truffle.espresso.classfile.perf.DebugCounter;
+import com.oracle.truffle.espresso.impl.ClassRegistry;
+import com.oracle.truffle.espresso.impl.Field;
+import com.oracle.truffle.espresso.impl.Klass;
+import com.oracle.truffle.espresso.impl.Member;
+import com.oracle.truffle.espresso.impl.Method;
+import com.oracle.truffle.espresso.impl.ObjectKlass;
+import com.oracle.truffle.espresso.meta.EspressoError;
+import com.oracle.truffle.espresso.meta.Meta;
+import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode;
+import com.oracle.truffle.espresso.nodes.methodhandle.MHLinkToNode;
import com.oracle.truffle.espresso.redefinition.ClassRedefinition;
import com.oracle.truffle.espresso.resolver.LinkResolver;
import com.oracle.truffle.espresso.runtime.EspressoContext;
@@ -66,8 +68,6 @@
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
import com.oracle.truffle.espresso.substitutions.JavaType;
-import java.util.logging.Level;
-
public final class Resolution {
static final DebugCounter CLASS_RESOLVE_COUNT = DebugCounter.create("ClassConstant.resolve calls");
static final DebugCounter FIELDREF_RESOLVE_COUNT = DebugCounter.create("FieldRef.resolve calls");
@@ -195,87 +195,32 @@ public static ResolvedClassConstant resolveClassConstant(ClassConstant.WithStrin
}
}
- /**
- *
5.4.3.2. Field Resolution
- *
- * To resolve an unresolved symbolic reference from D to a field in a class or interface C, the
- * symbolic reference to C given by the field reference must first be resolved (§5.4.3.1).
- * Therefore, any exception that can be thrown as a result of failure of resolution of a class
- * or interface reference can be thrown as a result of failure of field resolution. If the
- * reference to C can be successfully resolved, an exception relating to the failure of
- * resolution of the field reference itself can be thrown.
- *
- * When resolving a field reference, field resolution first attempts to look up the referenced
- * field in C and its superclasses:
- *
- * - If C declares a field with the name and descriptor specified by the field reference,
- * field lookup succeeds. The declared field is the result of the field lookup.
- *
- Otherwise, field lookup is applied recursively to the direct superinterfaces of the
- * specified class or interface C.
- *
- Otherwise, if C has a superclass S, field lookup is applied recursively to S.
- *
- Otherwise, field lookup fails.
- *
- *
- * Then:
- *
- * - If field lookup fails, field resolution throws a NoSuchFieldError.
- *
- Otherwise, if field lookup succeeds but the referenced field is not accessible
- * (§5.4.4) to D, field resolution throws an IllegalAccessError.
- *
- Otherwise, let < E, L1 > be the class or interface in which the referenced field is
- * actually declared and let L2 be the defining loader of D.
- *
- Given that the type of the referenced field is Tf, let T be Tf if Tf is not an array
- * type, and let T be the element type (§2.4) of Tf otherwise.
- *
- The Java Virtual Machine must impose the loading constraint that TL1 = TL2 (§5.3.4).
- *
- */
- private static Field lookupField(Klass seed, Symbol name, Symbol type) {
- Field f = seed.lookupDeclaredField(name, type);
- if (f != null) {
- return f;
- }
- for (Klass i : seed.getSuperInterfaces()) {
- f = lookupField(i, name, type);
- if (f != null) {
- return f;
- }
- }
- if (seed.getSuperKlass() != null) {
- return lookupField(seed.getSuperKlass(), name, type);
- }
- return null;
- }
-
public static Resolvable.ResolvedConstant resolveFieldRefConstant(FieldRefConstant.Indexes thiz, RuntimeConstantPool pool, @SuppressWarnings("unused") int thisIndex, ObjectKlass accessingKlass) {
FIELDREF_RESOLVE_COUNT.inc();
Klass holderKlass = getResolvedHolderKlass(thiz, pool, accessingKlass);
Symbol name = thiz.getName(pool);
Symbol type = thiz.getType(pool);
- Field field = lookupField(holderKlass, name, type);
- if (field == null) {
- ClassRedefinition classRedefinition = pool.getContext().getClassRedefinition();
- if (classRedefinition != null) {
- // could be due to ongoing redefinition
- classRedefinition.check();
- field = lookupField(holderKlass, name, type);
- }
- if (field == null) {
- Meta meta = pool.getContext().getMeta();
- EspressoException failure = EspressoException.wrap(Meta.initExceptionWithMessage(meta.java_lang_NoSuchFieldError, name.toString()), meta);
- Assumption missingFieldAssumption;
+ Meta meta = pool.getContext().getMeta();
+ Field field;
+ ClassRedefinition classRedefinition = null;
+ try {
+ try {
+ field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true);
+ } catch (EspressoException e) {
+ classRedefinition = pool.getContext().getClassRedefinition();
if (classRedefinition != null) {
- missingFieldAssumption = classRedefinition.getMissingFieldAssumption();
+ // could be due to ongoing redefinition
+ classRedefinition.check();
+ field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true);
} else {
- missingFieldAssumption = Assumption.ALWAYS_VALID;
+ throw e;
}
- return new MissingFieldRefConstant(failure, missingFieldAssumption);
}
+ } catch (EspressoException e) {
+ return new MissingFieldRefConstant(e, classRedefinition == null ? Assumption.ALWAYS_VALID : classRedefinition.getMissingFieldAssumption());
}
- memberDoAccessCheck(accessingKlass, holderKlass, field, pool.getContext().getMeta());
-
- field.checkLoadingConstraints(accessingKlass.getDefiningClassLoader(), field.getDeclaringKlass().getDefiningClassLoader());
-
return new ResolvedFieldRefConstant(field);
}
@@ -411,7 +356,7 @@ public static Resolvable.ResolvedConstant resolveInterfaceMethodRefConstant(Inte
Symbol name = thiz.getName(pool);
Symbol signature = thiz.getSignature(pool);
- Method method = LinkResolver.resolveSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true);
+ Method method = LinkResolver.resolveMethodSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true);
return new ResolvedInterfaceMethodRefConstant(method);
}
@@ -533,7 +478,7 @@ public static Resolvable.ResolvedConstant resolveClassMethodRefConstant(ClassMet
Symbol name = thiz.getName(pool);
Symbol signature = thiz.getSignature(pool);
- Method method = LinkResolver.resolveSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true);
+ Method method = LinkResolver.resolveMethodSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true);
if (method.isInvokeIntrinsic()) {
MHInvokeGenericNode.MethodHandleInvoker invoker = MHInvokeGenericNode.linkMethod(meta.getLanguage(), meta, accessingKlass, method, name, signature);
diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jni/JniEnv.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jni/JniEnv.java
index c637fbeb6553..76d835909ecb 100644
--- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jni/JniEnv.java
+++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jni/JniEnv.java
@@ -50,7 +50,7 @@
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import com.oracle.truffle.espresso.EspressoLanguage;
-import com.oracle.truffle.espresso.ffi.NativeAccess;
+import com.oracle.truffle.espresso.classfile.JavaKind;
import com.oracle.truffle.espresso.classfile.descriptors.ByteSequence;
import com.oracle.truffle.espresso.classfile.descriptors.ModifiedUtf8;
import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
@@ -59,6 +59,7 @@
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
import com.oracle.truffle.espresso.classfile.descriptors.Validation;
+import com.oracle.truffle.espresso.ffi.NativeAccess;
import com.oracle.truffle.espresso.ffi.NativeSignature;
import com.oracle.truffle.espresso.ffi.NativeType;
import com.oracle.truffle.espresso.ffi.Pointer;
@@ -70,7 +71,6 @@
import com.oracle.truffle.espresso.impl.Method;
import com.oracle.truffle.espresso.impl.ObjectKlass;
import com.oracle.truffle.espresso.meta.EspressoError;
-import com.oracle.truffle.espresso.classfile.JavaKind;
import com.oracle.truffle.espresso.meta.Meta;
import com.oracle.truffle.espresso.nodes.EspressoRootNode;
import com.oracle.truffle.espresso.nodes.bytecodes.ArrayLength;
@@ -446,7 +446,7 @@ private WeakHandles methodIds() {
if (fieldType != null) {
// Lookup only if name and type are known symbols.
klass.safeInitialize();
- field = klass.lookupField(fieldName, fieldType);
+ field = klass.lookupField(fieldName, fieldType, Klass.LookupMode.INSTANCE_ONLY);
assert field == null || field.getType().equals(fieldType);
}
}
diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java
index d3d45e68d890..287431e99fd0 100644
--- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java
+++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java
@@ -22,7 +22,6 @@
*/
package com.oracle.truffle.espresso.nodes;
-import static com.oracle.truffle.espresso.EspressoOptions.SpecComplianceMode.STRICT;
import static com.oracle.truffle.espresso.classfile.bytecode.Bytecodes.AALOAD;
import static com.oracle.truffle.espresso.classfile.bytecode.Bytecodes.AASTORE;
import static com.oracle.truffle.espresso.classfile.bytecode.Bytecodes.ACONST_NULL;
@@ -305,19 +304,16 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.espresso.EspressoLanguage;
import com.oracle.truffle.espresso.analysis.liveness.LivenessAnalysis;
+import com.oracle.truffle.espresso.bytecode.MapperBCI;
+import com.oracle.truffle.espresso.classfile.ExceptionHandler;
+import com.oracle.truffle.espresso.classfile.JavaKind;
+import com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute;
+import com.oracle.truffle.espresso.classfile.attributes.LineNumberTableAttribute;
import com.oracle.truffle.espresso.classfile.bytecode.BytecodeLookupSwitch;
import com.oracle.truffle.espresso.classfile.bytecode.BytecodeStream;
import com.oracle.truffle.espresso.classfile.bytecode.BytecodeTableSwitch;
import com.oracle.truffle.espresso.classfile.bytecode.Bytecodes;
-import com.oracle.truffle.espresso.bytecode.MapperBCI;
-import com.oracle.truffle.espresso.constantpool.CallSiteLink;
-import com.oracle.truffle.espresso.constantpool.Resolution;
-import com.oracle.truffle.espresso.constantpool.ResolvedDynamicConstant;
-import com.oracle.truffle.espresso.constantpool.ResolvedWithInvokerClassMethodRefConstant;
-import com.oracle.truffle.espresso.classfile.ClassfileParser;
-import com.oracle.truffle.espresso.constantpool.RuntimeConstantPool;
-import com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute;
-import com.oracle.truffle.espresso.classfile.attributes.LineNumberTableAttribute;
+import com.oracle.truffle.espresso.classfile.bytecode.VolatileArrayAccess;
import com.oracle.truffle.espresso.classfile.constantpool.ClassConstant;
import com.oracle.truffle.espresso.classfile.constantpool.DoubleConstant;
import com.oracle.truffle.espresso.classfile.constantpool.DynamicConstant;
@@ -332,6 +328,12 @@
import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
+import com.oracle.truffle.espresso.classfile.perf.DebugCounter;
+import com.oracle.truffle.espresso.constantpool.CallSiteLink;
+import com.oracle.truffle.espresso.constantpool.Resolution;
+import com.oracle.truffle.espresso.constantpool.ResolvedDynamicConstant;
+import com.oracle.truffle.espresso.constantpool.ResolvedWithInvokerClassMethodRefConstant;
+import com.oracle.truffle.espresso.constantpool.RuntimeConstantPool;
import com.oracle.truffle.espresso.impl.ArrayKlass;
import com.oracle.truffle.espresso.impl.Field;
import com.oracle.truffle.espresso.impl.Klass;
@@ -339,8 +341,6 @@
import com.oracle.truffle.espresso.impl.Method.MethodVersion;
import com.oracle.truffle.espresso.impl.ObjectKlass;
import com.oracle.truffle.espresso.meta.EspressoError;
-import com.oracle.truffle.espresso.classfile.ExceptionHandler;
-import com.oracle.truffle.espresso.classfile.JavaKind;
import com.oracle.truffle.espresso.meta.Meta;
import com.oracle.truffle.espresso.nodes.helper.EspressoReferenceArrayStoreNode;
import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode.MethodHandleInvoker;
@@ -348,7 +348,6 @@
import com.oracle.truffle.espresso.nodes.quick.CheckCastQuickNode;
import com.oracle.truffle.espresso.nodes.quick.InstanceOfQuickNode;
import com.oracle.truffle.espresso.nodes.quick.QuickNode;
-import com.oracle.truffle.espresso.classfile.bytecode.VolatileArrayAccess;
import com.oracle.truffle.espresso.nodes.quick.interop.ArrayLengthQuickNode;
import com.oracle.truffle.espresso.nodes.quick.interop.ByteArrayLoadQuickNode;
import com.oracle.truffle.espresso.nodes.quick.interop.ByteArrayStoreQuickNode;
@@ -377,9 +376,9 @@
import com.oracle.truffle.espresso.nodes.quick.invoke.InvokeStaticQuickNode;
import com.oracle.truffle.espresso.nodes.quick.invoke.InvokeVirtualQuickNode;
import com.oracle.truffle.espresso.nodes.quick.invoke.inline.InlinedMethodNode;
-import com.oracle.truffle.espresso.classfile.perf.DebugCounter;
import com.oracle.truffle.espresso.resolver.CallKind;
import com.oracle.truffle.espresso.resolver.CallSiteType;
+import com.oracle.truffle.espresso.resolver.FieldAccessType;
import com.oracle.truffle.espresso.resolver.LinkResolver;
import com.oracle.truffle.espresso.resolver.ResolvedCall;
import com.oracle.truffle.espresso.runtime.EspressoContext;
@@ -1308,17 +1307,28 @@ private Object executeBodyFromBCI(VirtualFrame frame, int startBCI, int startTop
curBCI = returnValueBci;
continue loop;
}
- // @formatter:off
// TODO(peterssen): Order shuffled.
- case GETSTATIC : // fall through
- case GETFIELD : top += getField(frame, top,
- resolveField(curOpcode, /* Quickenable -> read from original code for thread safety */ readOriginalCPI(curBCI)),
- curBCI, curOpcode, statementIndex); break;
- case PUTSTATIC : // fall through
- case PUTFIELD : top += putField(frame, top,
- resolveField(curOpcode, /* Quickenable -> read from original code for thread safety */ readOriginalCPI(curBCI)),
- curBCI, curOpcode, statementIndex); break;
-
+ case GETSTATIC:
+ top += getField(frame, top,
+ resolveField(curOpcode, /*- Quickenable -> read from original code for thread safety */ readOriginalCPI(curBCI)),
+ curBCI, curOpcode, statementIndex, FieldAccessType.GetStatic);
+ break;
+ case GETFIELD:
+ top += getField(frame, top,
+ resolveField(curOpcode, /*- Quickenable -> read from original code for thread safety */ readOriginalCPI(curBCI)),
+ curBCI, curOpcode, statementIndex, FieldAccessType.GetInstance);
+ break;
+ case PUTSTATIC:
+ top += putField(frame, top,
+ resolveField(curOpcode, /*- Quickenable -> read from original code for thread safety */ readOriginalCPI(curBCI)),
+ curBCI, curOpcode, statementIndex, FieldAccessType.PutStatic);
+ break;
+ case PUTFIELD:
+ top += putField(frame, top,
+ resolveField(curOpcode, /*- Quickenable -> read from original code for thread safety */ readOriginalCPI(curBCI)),
+ curBCI, curOpcode, statementIndex, FieldAccessType.PutInstance);
+ break;
+ // @formatter:off
case INVOKEVIRTUAL: // fall through
case INVOKESPECIAL: // fall through
case INVOKESTATIC: // fall through
@@ -2691,72 +2701,19 @@ private long checkNonZero(long value) {
* curBCI = bs.next(curBCI);
*
*/
- private int putField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) {
+ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex, FieldAccessType mode) {
assert opcode == PUTFIELD || opcode == PUTSTATIC;
CompilerAsserts.partialEvaluationConstant(field);
+ CompilerAsserts.partialEvaluationConstant(mode);
- /*
- * PUTFIELD: Otherwise, if the resolved field is a static field, putfield throws an
- * IncompatibleClassChangeError.
- *
- * PUTSTATIC: Otherwise, if the resolved field is not a static (class) field or an interface
- * field, putstatic throws an IncompatibleClassChangeError.
- */
- if (field.isStatic() != (opcode == PUTSTATIC)) {
- enterLinkageExceptionProfile();
- throw throwBoundary(getMethod().getMeta().java_lang_IncompatibleClassChangeError,
- "Expected %s field %s.%s",
- (opcode == PUTSTATIC) ? "static" : "non-static",
- field.getDeclaringKlass().getName(),
- field.getName());
- }
-
- /*
- * PUTFIELD: Otherwise, if the field is final, it must be declared in the current class, and
- * the instruction must occur in an instance initialization method () of the current
- * class. Otherwise, an IllegalAccessError is thrown.
- *
- * PUTSTATIC: Otherwise, if the field is final, it must be declared in the current class,
- * and the instruction must occur in the method of the current class. Otherwise, an
- * IllegalAccessError is thrown.
- */
- if (field.isFinalFlagSet()) {
- if (field.getDeclaringKlass() != getDeclaringKlass()) {
- enterLinkageExceptionProfile();
- throw throwBoundary(getMethod().getMeta().java_lang_IllegalAccessError,
- "Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
- (opcode == PUTSTATIC) ? "static" : "non-static",
- field.getDeclaringKlass().getName(),
- field.getName(),
- getDeclaringKlass().getName());
- }
-
- boolean enforceInitializerCheck = (getLanguage().getSpecComplianceMode() == STRICT) ||
- // HotSpot enforces this only for >= Java 9 (v53) .class files.
- field.getDeclaringKlass().getMajorVersion() >= ClassfileParser.JAVA_9_VERSION;
-
- if (enforceInitializerCheck &&
- ((opcode == PUTFIELD && !getMethod().isConstructor()) ||
- (opcode == PUTSTATIC && !getMethod().isClassInitializer()))) {
- enterLinkageExceptionProfile();
- throw throwBoundary(getMethod().getMeta().java_lang_IllegalAccessError,
- "Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
- (opcode == PUTSTATIC) ? "static" : "non-static",
- field.getDeclaringKlass().getName(),
- field.getName(),
- getMethod().getName(),
- (opcode == PUTSTATIC) ? "" : "");
- }
- }
-
- assert field.isStatic() == (opcode == PUTSTATIC);
+ LinkResolver.resolveFieldAccess(getMeta(), getDeclaringKlass(), getMethod(), field, mode);
byte typeHeader = field.getType().byteAt(0);
int slotCount = (typeHeader == 'J' || typeHeader == 'D') ? 2 : 1;
assert slotCount == field.getKind().getSlotCount();
int slot = top - slotCount - 1; // -receiver
StaticObject receiver;
- if (opcode == PUTSTATIC) {
+ if (mode.isStatic()) {
receiver = initializeAndGetStatics(field);
} else {
if (!noForeignObjects.isValid()) {
@@ -2857,31 +2814,16 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o
* curBCI = bs.next(curBCI);
*
*/
- private int getField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex) {
+ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int opcode, int statementIndex, FieldAccessType mode) {
assert opcode == GETFIELD || opcode == GETSTATIC;
CompilerAsserts.partialEvaluationConstant(field);
- /*
- * GETFIELD: Otherwise, if the resolved field is a static field, getfield throws an
- * IncompatibleClassChangeError.
- *
- * GETSTATIC: Otherwise, if the resolved field is not a static (class) field or an interface
- * field, getstatic throws an IncompatibleClassChangeError.
- */
- if (field.isStatic() != (opcode == GETSTATIC)) {
- enterLinkageExceptionProfile();
- throw throwBoundary(getMethod().getMeta().java_lang_IncompatibleClassChangeError,
- "Expected %s field %s.%s",
- (opcode == GETSTATIC) ? "static" : "non-static",
- field.getDeclaringKlass().getNameAsString(),
- field.getNameAsString());
- }
- assert field.isStatic() == (opcode == GETSTATIC);
+ LinkResolver.resolveFieldAccess(getMeta(), getDeclaringKlass(), getMethod(), field, mode);
int slot = top - 1;
StaticObject receiver;
- if (opcode == GETSTATIC) {
+ if (mode.isStatic()) {
receiver = initializeAndGetStatics(field);
} else {
if (!noForeignObjects.isValid()) {
@@ -2903,7 +2845,7 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o
instrumentation.notifyFieldAccess(frame, statementIndex, field, receiver);
}
- int resultAt = field.isStatic() ? top : (top - 1);
+ int resultAt = mode.isStatic() ? top : (top - 1);
// @formatter:off
byte typeHeader = field.getType().byteAt(0);
switch (typeHeader) {
diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/FieldAccessType.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/FieldAccessType.java
new file mode 100644
index 000000000000..b8b13fb13886
--- /dev/null
+++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/FieldAccessType.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.truffle.espresso.resolver;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.espresso.classfile.Constants;
+import com.oracle.truffle.espresso.classfile.bytecode.Bytecodes;
+import com.oracle.truffle.espresso.meta.EspressoError;
+
+public enum FieldAccessType {
+ GetStatic(true, false),
+ PutStatic(true, true),
+ GetInstance(false, false),
+ PutInstance(false, true);
+
+ private final boolean isStatic;
+ private final boolean isPut;
+
+ FieldAccessType(boolean isStatic, boolean isPut) {
+ this.isStatic = isStatic;
+ this.isPut = isPut;
+ }
+
+ public boolean isStatic() {
+ return isStatic;
+ }
+
+ public boolean isPut() {
+ return isPut;
+ }
+
+ public static FieldAccessType fromOpCode(int opcode) {
+ switch (opcode) {
+ case Bytecodes.GETSTATIC:
+ return GetStatic;
+ case Bytecodes.PUTSTATIC:
+ return PutStatic;
+ case Bytecodes.GETFIELD:
+ return GetInstance;
+ case Bytecodes.PUTFIELD:
+ return PutInstance;
+ default:
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ throw EspressoError.shouldNotReachHere(Bytecodes.nameOf(opcode));
+ }
+ }
+
+ public static FieldAccessType fromRefKind(int refKind) {
+ switch (refKind) {
+ case Constants.REF_getField:
+ return GetInstance;
+ case Constants.REF_getStatic:
+ return GetStatic;
+ case Constants.REF_putField:
+ return PutInstance;
+ case Constants.REF_putStatic:
+ return PutStatic;
+ default:
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ throw EspressoError.shouldNotReachHere("refkind: " + refKind);
+ }
+ }
+}
diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/LinkResolver.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/LinkResolver.java
index 44c754b35356..3943f4f8c687 100644
--- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/LinkResolver.java
+++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/resolver/LinkResolver.java
@@ -23,16 +23,19 @@
package com.oracle.truffle.espresso.resolver;
+import static com.oracle.truffle.espresso.EspressoOptions.SpecComplianceMode.STRICT;
import static com.oracle.truffle.espresso.meta.EspressoError.cat;
import java.util.Locale;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
-import com.oracle.truffle.espresso.constantpool.Resolution;
+import com.oracle.truffle.espresso.classfile.ClassfileParser;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
+import com.oracle.truffle.espresso.constantpool.Resolution;
+import com.oracle.truffle.espresso.impl.Field;
import com.oracle.truffle.espresso.impl.Klass;
import com.oracle.truffle.espresso.impl.Method;
import com.oracle.truffle.espresso.impl.ObjectKlass;
@@ -40,10 +43,42 @@
import com.oracle.truffle.espresso.meta.Meta;
public final class LinkResolver {
+
+ /**
+ * Symbolically resolves a field.
+ *
+ * @param accessingKlass The class requesting resolution.
+ * @param name The name of the field.
+ * @param type The type of the field.
+ * @param symbolicHolder The holder of the field, as described in the constant pool.
+ * @param accessCheck Whether to perform access checks on the resolved field.
+ * @param loadingConstraints Whether to check loading constraints on the resolved field.
+ */
+ public static Field resolveFieldSymbol(Meta meta, ObjectKlass accessingKlass,
+ Symbol name, Symbol type, Klass symbolicHolder,
+ boolean accessCheck, boolean loadingConstraints) {
+ return LinkResolverImpl.resolveFieldSymbol(meta, accessingKlass, name, type, symbolicHolder, accessCheck, loadingConstraints);
+ }
+
+ /**
+ * Resolve a field access site, given the symbolic resolution of the method. This ensures the
+ * access is valid for the given site. In particular, this checks that static fields are only
+ * accessed with static accesses, and that field writes to final fields are done only in the
+ * constructor or class initializer.
+ *
+ * @param currentKlass The class in which the field access appears.
+ * @param currentMethod The method in which the field access appears.
+ * @param symbolicResolution The result of symbolic resolution of the field declared in the
+ * access site.
+ * @param fieldAccessType The {@link FieldAccessType} representing the access site to resolve.
+ */
+ public static Field resolveFieldAccess(Meta meta, Klass currentKlass, Method currentMethod, Field symbolicResolution, FieldAccessType fieldAccessType) {
+ return LinkResolverImpl.resolveFieldAccess(meta, symbolicResolution, fieldAccessType, currentKlass, currentMethod);
+ }
+
/**
* Symbolically resolves a method.
*
- * @param meta
* @param accessingKlass The class requesting resolution.
* @param name The name of the method.
* @param signature The signature of the method.
@@ -51,17 +86,16 @@ public final class LinkResolver {
* @param accessCheck Whether to perform access checks on the resolved method.
* @param loadingConstraints Whether to check loading constraints on the resolved method.
*/
- public static Method resolveSymbol(Meta meta, ObjectKlass accessingKlass,
+ public static Method resolveMethodSymbol(Meta meta, ObjectKlass accessingKlass,
Symbol name, Symbol signature, Klass symbolicHolder,
boolean interfaceLookup,
boolean accessCheck, boolean loadingConstraints) {
- return LinkResolverImpl.resolveSymbol(meta, accessingKlass, name, signature, symbolicHolder, interfaceLookup, accessCheck, loadingConstraints);
+ return LinkResolverImpl.resolveMethodSymbol(meta, accessingKlass, name, signature, symbolicHolder, interfaceLookup, accessCheck, loadingConstraints);
}
/**
* Resolve a call-site given the symbolic resolution of the method in the constant pool.
*
- * @param meta
* @param currentKlass The class in which the call site to resolve appears.
* @param symbolicResolution The result of the symbolic resolution of the method declared in the
* call site.
@@ -82,9 +116,86 @@ final class LinkResolverImpl {
private static final String AN_INTERFACE = "an interface";
private static final String A_CLASS = "a class";
+ private static final String STATIC = "static";
+ private static final String NON_STATIC = "non-static";
+ private static final String INIT = "";
+ private static final String CLINIT = "";
@TruffleBoundary
- public static Method resolveSymbol(Meta meta, ObjectKlass accessingKlass, Symbol name, Symbol signature, Klass symbolicHolder,
+ public static Field resolveFieldSymbol(Meta meta, ObjectKlass accessingKlass,
+ Symbol name, Symbol type, Klass symbolicHolder,
+ boolean accessCheck, boolean loadingConstraints) {
+ Field f = symbolicHolder.lookupField(name, type);
+ if (f == null) {
+ throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchFieldError, name.toString());
+ }
+ if (accessCheck) {
+ Resolution.memberDoAccessCheck(accessingKlass, symbolicHolder, f, meta);
+ }
+ if (loadingConstraints) {
+ f.checkLoadingConstraints(accessingKlass.getDefiningClassLoader(), f.getDeclaringKlass().getDefiningClassLoader());
+ }
+ return f;
+ }
+
+ public static Field resolveFieldAccess(Meta meta, Field field, FieldAccessType fieldAccessType,
+ Klass currentKlass, Method currentMethod) {
+ /*
+ * PUTFIELD/GETFIELD: Otherwise, if the resolved field is a static field, putfield throws an
+ * IncompatibleClassChangeError.
+ *
+ * PUTSTATIC/GETSTATIC: Otherwise, if the resolved field is not a static (class) field or an
+ * interface field, putstatic throws an IncompatibleClassChangeError.
+ */
+
+ if (fieldAccessType.isStatic() != field.isStatic()) {
+ throw throwBoundary(meta, meta.java_lang_IncompatibleClassChangeError,
+ "Expected %s field %s.%s",
+ (fieldAccessType.isStatic()) ? STATIC : NON_STATIC,
+ field.getDeclaringKlass().getName(),
+ field.getName());
+ }
+ if (fieldAccessType.isPut()) {
+ /*
+ * PUTFIELD: Otherwise, if the field is final, it must be declared in the current class,
+ * and the instruction must occur in an instance initialization method () of the
+ * current class. Otherwise, an IllegalAccessError is thrown.
+ *
+ * PUTSTATIC: Otherwise, if the field is final, it must be declared in the current
+ * class, and the instruction must occur in the method of the current class.
+ * Otherwise, an IllegalAccessError is thrown.
+ */
+ if (field.isFinalFlagSet()) {
+ if (field.getDeclaringKlass() != currentKlass) {
+ throw throwBoundary(meta, meta.java_lang_IllegalAccessError,
+ "Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
+ (fieldAccessType.isStatic()) ? STATIC : NON_STATIC,
+ field.getDeclaringKlass().getName(),
+ field.getName(),
+ currentKlass.getName());
+ }
+ boolean enforceInitializerCheck = (meta.getLanguage().getSpecComplianceMode() == STRICT) ||
+ // HotSpot enforces this only for >= Java 9 (v53) .class files.
+ field.getDeclaringKlass().getMajorVersion() >= ClassfileParser.JAVA_9_VERSION;
+ if (enforceInitializerCheck) {
+ if (!((fieldAccessType.isStatic() && currentMethod.isClassInitializer()) ||
+ (!fieldAccessType.isStatic() && currentMethod.isConstructor()))) {
+ throw throwBoundary(meta, meta.java_lang_IllegalAccessError,
+ "Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ",
+ (fieldAccessType.isStatic()) ? STATIC : NON_STATIC,
+ field.getDeclaringKlass().getName(),
+ field.getName(),
+ currentMethod.getName(),
+ (fieldAccessType.isStatic()) ? CLINIT : INIT);
+ }
+ }
+ }
+ }
+ return field;
+ }
+
+ @TruffleBoundary
+ public static Method resolveMethodSymbol(Meta meta, ObjectKlass accessingKlass, Symbol name, Symbol signature, Klass symbolicHolder,
boolean interfaceLookup,
boolean accessCheck, boolean loadingConstraints) {
Method resolved;
@@ -132,7 +243,7 @@ public static ResolvedCall resolveCallSite(Meta meta, Klass currentKlass, Method
// invokeinterface instruction throws an IncompatibleClassChangeError.
if (resolved.isStatic() ||
(meta.getJavaVersion().java8OrEarlier() && resolved.isPrivate())) {
- throw throwBoundary(meta, meta.java_lang_IncompatibleClassChangeError, "Expected instance method '%s.%s%s'",
+ throw throwBoundary(meta, meta.java_lang_IncompatibleClassChangeError, "Expected instance not static method '%s.%s%s'",
resolved.getDeclaringKlass().getName(),
resolved.getName(),
resolved.getRawSignature());
@@ -155,7 +266,7 @@ public static ResolvedCall resolveCallSite(Meta meta, Klass currentKlass, Method
// Otherwise, if the resolved method is a class (static) method, the invokevirtual
// instruction throws an IncompatibleClassChangeError.
if (resolved.isStatic()) {
- throw throwBoundary(meta, meta.java_lang_IncompatibleClassChangeError, "Expected instance not static method '%s.%s%s'",
+ throw throwBoundary(meta, meta.java_lang_IncompatibleClassChangeError, "Expected instance method '%s.%s%s'",
resolved.getDeclaringKlass().getName(),
resolved.getName(),
resolved.getRawSignature());
diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_java_lang_invoke_MethodHandleNatives.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_java_lang_invoke_MethodHandleNatives.java
index 7ad863eb1564..7e0a2d95072c 100644
--- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_java_lang_invoke_MethodHandleNatives.java
+++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/substitutions/Target_java_lang_invoke_MethodHandleNatives.java
@@ -22,6 +22,38 @@
*/
package com.oracle.truffle.espresso.substitutions;
+import static com.oracle.truffle.espresso.classfile.Constants.ACC_STATIC;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_LIMIT;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_NONE;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_getField;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_getStatic;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeInterface;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeSpecial;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeStatic;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeVirtual;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_newInvokeSpecial;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_putField;
+import static com.oracle.truffle.espresso.classfile.Constants.REF_putStatic;
+import static com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics.PolySigIntrinsics.InvokeGeneric;
+import static com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics.PolySigIntrinsics.None;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.ALL_KINDS;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.CONSTANTS;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.CONSTANTS_BEFORE_16;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.LM_UNCONDITIONAL;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_CALLER_SENSITIVE;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_IS_FIELD;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_IS_METHOD;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_REFERENCE_KIND_MASK;
+import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.graalvm.collections.Pair;
+
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Bind;
@@ -29,7 +61,6 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.espresso.EspressoLanguage;
-import com.oracle.truffle.espresso.constantpool.Resolution;
import com.oracle.truffle.espresso.classfile.descriptors.ByteSequence;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
@@ -51,38 +82,6 @@
import com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics;
import com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics.PolySigIntrinsics;
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
-import org.graalvm.collections.Pair;
-
-import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandle;
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.oracle.truffle.espresso.meta.EspressoError.cat;
-import static com.oracle.truffle.espresso.classfile.Constants.ACC_STATIC;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_LIMIT;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_NONE;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_getField;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_getStatic;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeInterface;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeSpecial;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeStatic;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeVirtual;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_newInvokeSpecial;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_putField;
-import static com.oracle.truffle.espresso.classfile.Constants.REF_putStatic;
-import static com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics.PolySigIntrinsics.InvokeGeneric;
-import static com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics.PolySigIntrinsics.None;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.ALL_KINDS;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.CONSTANTS;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.CONSTANTS_BEFORE_16;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.LM_UNCONDITIONAL;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_CALLER_SENSITIVE;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_IS_FIELD;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_IS_METHOD;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_REFERENCE_KIND_MASK;
-import static com.oracle.truffle.espresso.substitutions.Target_java_lang_invoke_MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
@EspressoSubstitutions
public final class Target_java_lang_invoke_MethodHandleNatives {
@@ -465,7 +464,13 @@ StaticObject doCached(
if (Constants.flagHas(flags, MN_IS_FIELD)) {
isFieldProfile.enter();
Symbol t = lookupType(meta, desc);
- plantFieldMemberName(memberName, resolutionKlass, name, t, refKind, callerKlass, doAccessChecks, doConstraintsChecks, meta, getLanguage());
+ // Field member name resolution skips several checks:
+ // - Access checks
+ // - Static fields are accessed statically
+ // - Final fields and ref_put*
+ // These are done when needed by JDK code.
+ Field f = LinkResolver.resolveFieldSymbol(meta, callerKlass, name, t, resolutionKlass, false, doConstraintsChecks);
+ plantResolvedField(memberName, f, refKind, meta, meta.getLanguage());
return memberName;
}
@@ -494,7 +499,7 @@ StaticObject doCached(
}
Symbol sig = lookupSignature(meta, desc, mhMethodId);
- Method m = LinkResolver.resolveSymbol(meta, callerKlass, name, sig, resolutionKlass, resolutionKlass.isInterface(), doAccessChecks, doConstraintsChecks);
+ Method m = LinkResolver.resolveMethodSymbol(meta, callerKlass, name, sig, resolutionKlass, resolutionKlass.isInterface(), doAccessChecks, doConstraintsChecks);
ResolvedCall resolvedCall = LinkResolver.resolveCallSite(meta, callerKlass, m, CallSiteType.fromRefKind(refKind), resolutionKlass);
plantResolvedMethod(memberName, resolvedCall, meta);
@@ -614,26 +619,6 @@ private static void plant(StaticObject memberName, Method target, Meta meta, int
meta.java_lang_invoke_MemberName_clazz.setObject(memberName, target.getDeclaringKlass().mirror());
}
- private static void plantFieldMemberName(StaticObject memberName,
- Klass resolutionKlass, Symbol name, Symbol type,
- int refKind,
- ObjectKlass callerKlass,
- boolean accessCheck,
- boolean constraintsCheck,
- Meta meta, EspressoLanguage language) {
- Field field = doFieldLookup(resolutionKlass, name, type);
- if (field == null) {
- throw meta.throwExceptionWithMessage(meta.java_lang_NoSuchFieldError, cat("Failed lookup for field ", resolutionKlass.getName(), "#", name, ":", type));
- }
- if (accessCheck) {
- Resolution.memberDoAccessCheck(callerKlass, field.getDeclaringKlass(), field, meta);
- }
- if (constraintsCheck) {
- field.checkLoadingConstraints(callerKlass.getDefiningClassLoader(), resolutionKlass.getDefiningClassLoader());
- }
- plantResolvedField(memberName, field, refKind, meta, language);
- }
-
private static void plantResolvedField(StaticObject memberName, Field field, int refKind, Meta meta, EspressoLanguage language) {
meta.HIDDEN_VMTARGET.setHiddenObject(memberName, field.getDeclaringKlass());
meta.HIDDEN_VMINDEX.setHiddenObject(memberName, Target_sun_misc_Unsafe.slotToGuestOffset(field.getSlot(), field.isStatic(), language));
@@ -713,23 +698,6 @@ private static int getFieldFlags(int refKind, Field fd) {
return res;
}
- private static Field doFieldLookup(Klass resolutionKlass, Symbol name, Symbol sig) {
- if (CompilerDirectives.isPartialEvaluationConstant(resolutionKlass)) {
- return lookupField(resolutionKlass, name, sig);
- } else {
- return lookupFieldBoundary(resolutionKlass, name, sig);
- }
- }
-
- private static Field lookupField(Klass resolutionKlass, Symbol name, Symbol sig) {
- return resolutionKlass.lookupField(name, sig);
- }
-
- @TruffleBoundary
- private static Field lookupFieldBoundary(Klass resolutionKlass, Symbol name, Symbol sig) {
- return lookupField(resolutionKlass, name, sig);
- }
-
// endregion MemberName planting
// region Helper methods