use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class MethodVerifier method verifyGetField.
private void verifyGetField(int bci, OperandStack stack, int curOpcode) {
// Check CP validity
PoolConstant pc = poolAt(code.readCPI(bci));
verifyGuarantee(pc.tag() == ConstantPool.Tag.FIELD_REF, "Invalid CP constant for GETFIELD: " + pc.toString());
pc.validate(pool);
// Obtain field info
FieldRefConstant frc = (FieldRefConstant) pc;
assert Validation.validFieldDescriptor(frc.getType(pool));
Symbol<Type> type = frc.getType(pool);
if (curOpcode == GETFIELD) {
// Pop and check receiver
assert Validation.validClassNameEntry(frc.getHolderKlassName(pool));
Symbol<Type> fieldHolderType = getTypes().fromName(frc.getHolderKlassName(pool));
Operand fieldHolder = kindToOperand(fieldHolderType);
Operand receiver = checkInitAccess(stack.popRef(fieldHolder), fieldHolder);
checkProtectedMember(receiver, fieldHolderType, frc, false);
verifyGuarantee(!receiver.isArrayType(), "Trying to access field of an array type: " + receiver);
}
// push result
Operand op = kindToOperand(type);
stack.push(op);
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class MethodVerifier method verifyInvokeVirtual.
private void verifyInvokeVirtual(int bci, OperandStack stack) {
// Check CP validity
MethodRefConstant mrc = getMethodRefConstant(bci);
Symbol<Name> calledMethodName = mrc.getName(pool);
// Check guest is not invoking <clinit>
verifyGuarantee(!isClassInit(calledMethodName), "Invocation of class initializer!");
// Only INVOKESPECIAL can call <init>
verifyGuarantee(!isInstanceInit(calledMethodName), "Invocation of instance initializer with opcode other than INVOKESPECIAL");
Operand returnOp = popSignatureGetReturnOP(stack, mrc);
assert Validation.validClassNameEntry(mrc.getHolderKlassName(pool));
Symbol<Type> methodHolder = getTypes().fromName(mrc.getHolderKlassName(pool));
Operand methodHolderOp = kindToOperand(methodHolder);
Operand stackOp = checkInit(stack.popRef(methodHolderOp));
// Perform protected method access checks
checkProtectedMember(stackOp, methodHolder, mrc, true);
if (!(returnOp == Void)) {
stack.push(returnOp);
}
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class MethodVerifier method checkExceptionHandlers.
/**
* Checks that an instruction can merge into all its handlers.
*/
private void checkExceptionHandlers(int nextBCI, Locals locals) {
for (int i = 0; i < exceptionHandlers.length; i++) {
ExceptionHandler handler = exceptionHandlers[i];
if (nextBCI >= handler.getStartBCI() && nextBCI < handler.getEndBCI()) {
OperandStack stack = new OperandStack(1);
Symbol<Type> catchType = handler.getCatchType();
stack.push(catchType == null ? jlThrowable : new ReferenceOperand(catchType, thisKlass));
StackFrame oldFrame = stackFrames[handler.getHandlerBCI()];
StackFrame newFrame = mergeFrames(stack, locals, oldFrame);
if (isStatus(handlerStatus[i], UNENCOUNTERED) || oldFrame != newFrame) {
handlerStatus[i] = setStatus(handlerStatus[i], NONVERIFIED);
}
if (calledConstructor) {
handlerStatus[i] = setConstructorStatus(handlerStatus[i], CALLEDCONSTRUCTOR);
} else {
handlerStatus[i] = setConstructorStatus(handlerStatus[i], NOCONSTRUCTORCALLED);
}
stackFrames[handler.getHandlerBCI()] = newFrame;
}
}
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class ClassfileParser method parseField.
private ParserField parseField(boolean isInterface) {
int fieldFlags = stream.readU2();
int nameIndex = stream.readU2();
int typeIndex = stream.readU2();
pool.utf8At(nameIndex).validateFieldName();
final Symbol<Name> name = pool.symbolAt(nameIndex, "field name");
verifyFieldFlags(name, fieldFlags, isInterface);
final boolean isStatic = Modifier.isStatic(fieldFlags);
pool.utf8At(typeIndex).validateType(false);
Symbol<ModifiedUTF8> rawDescriptor = pool.symbolAt(typeIndex, "field descriptor");
final Symbol<Type> descriptor = Types.fromSymbol(rawDescriptor);
if (descriptor == null) {
throw ConstantPool.classFormatError("Invalid descriptor: " + rawDescriptor);
}
final int attributeCount = stream.readU2();
final Attribute[] fieldAttributes = spawnAttributesArray(attributeCount);
ConstantValueAttribute constantValue = null;
CommonAttributeParser commonAttributeParser = new CommonAttributeParser(InfoType.Field);
for (int i = 0; i < attributeCount; ++i) {
final int attributeNameIndex = stream.readU2();
final Symbol<Name> attributeName = pool.symbolAt(attributeNameIndex, "attribute name");
final int attributeSize = stream.readS4();
final int startPosition = stream.getPosition();
if (isStatic && attributeName.equals(Name.ConstantValue)) {
if (constantValue != null) {
throw ConstantPool.classFormatError("Duplicate ConstantValue attribute");
}
fieldAttributes[i] = constantValue = new ConstantValueAttribute(stream.readU2());
if (constantValue.getConstantValueIndex() == 0) {
throw ConstantPool.classFormatError("Invalid ConstantValue index");
}
} else if (attributeName.equals(Name.Synthetic)) {
fieldFlags |= ACC_SYNTHETIC;
fieldAttributes[i] = new Attribute(attributeName, null);
} else if (majorVersion >= JAVA_1_5_VERSION) {
Attribute attr = commonAttributeParser.parseCommonAttribute(attributeName, attributeSize);
// stream.skip(attributeSize);
fieldAttributes[i] = attr == null ? new Attribute(attributeName, stream.readByteArray(attributeSize)) : attr;
} else {
// stream.skip(attributeSize);
fieldAttributes[i] = new Attribute(attributeName, stream.readByteArray(attributeSize));
}
if (attributeSize != stream.getPosition() - startPosition) {
throw ConstantPool.classFormatError("Invalid attribute_length for " + attributeName + " attribute");
}
}
final JavaKind kind = Types.getJavaKind(descriptor);
if (kind == JavaKind.Void) {
throw ConstantPool.classFormatError("Fields cannot be of type void");
}
if (constantValue != null) {
Tag tag = pool.tagAt(constantValue.getConstantValueIndex());
boolean valid = false;
switch(kind) {
// fall through
case Boolean:
// fall through
case Byte:
// fall through
case Short:
// fall through
case Char:
case // fall through
Int:
valid = (tag == Tag.INTEGER);
break;
case Float:
valid = (tag == Tag.FLOAT);
break;
case Long:
valid = (tag == Tag.LONG);
break;
case Double:
valid = (tag == Tag.DOUBLE);
break;
case Object:
valid = (tag == Tag.STRING) && descriptor.equals(Type.java_lang_String);
break;
default:
{
throw ConstantPool.classFormatError("Cannot have ConstantValue for fields of type " + kind);
}
}
if (!valid) {
throw ConstantPool.classFormatError("ConstantValue attribute does not match field type");
}
}
return new ParserField(fieldFlags, name, descriptor, fieldAttributes);
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Type in project graal by oracle.
the class ClassfileParser method parseClassImpl.
private ParserKlass parseClassImpl() {
readMagic();
minorVersion = stream.readU2();
majorVersion = stream.readU2();
verifyVersion(majorVersion, minorVersion);
try (DebugCloseable closeable = CONSTANT_POOL.scope(context.getTimers())) {
this.pool = ConstantPool.parse(context.getLanguage(), stream, this, classDefinitionInfo.patches, context, majorVersion, minorVersion);
}
// JVM_ACC_MODULE is defined in JDK-9 and later.
if (majorVersion >= JAVA_9_VERSION) {
classFlags = stream.readU2() & (JVM_RECOGNIZED_CLASS_MODIFIERS | ACC_MODULE);
} else {
classFlags = stream.readU2() & (JVM_RECOGNIZED_CLASS_MODIFIERS);
}
if ((classFlags & ACC_INTERFACE) != 0 && majorVersion < JAVA_6_VERSION) {
// Set abstract bit for old class files for backward compatibility
classFlags |= ACC_ABSTRACT;
}
boolean isModule = (classFlags & ACC_MODULE) != 0;
if (isModule) {
throw ConstantPool.noClassDefFoundError(classType + " is not a class because access_flag ACC_MODULE is set");
}
if (badConstantSeen != null) {
// https://bugs.openjdk.java.net/browse/JDK-8175383
throw ConstantPool.classFormatError(String.format("Unknown constant tag %s [in class file %s]", badConstantSeen, classfile));
}
verifyClassFlags(classFlags, majorVersion);
// this class
int thisKlassIndex = stream.readU2();
Symbol<Name> thisKlassName = pool.classAt(thisKlassIndex).getName(pool);
final boolean isInterface = Modifier.isInterface(classFlags);
// TODO(peterssen): Verify class names.
Symbol<Type> thisKlassType = context.getTypes().fromName(thisKlassName);
if (Types.isPrimitive(thisKlassType) || Types.isArray(thisKlassType)) {
throw ConstantPool.classFormatError(".this_class cannot be array nor primitive " + classType);
}
// Update classType which could be null previously to reflect the name in the constant pool.
classType = thisKlassType;
// Checks if name in class file matches requested name
if (requestedClassType != null && !classDefinitionInfo.isHidden() && !requestedClassType.equals(classType)) {
throw ConstantPool.noClassDefFoundError(classType + " (wrong name: " + requestedClassType + ")");
}
Symbol<Type> superKlass = parseSuperKlass();
if (!Type.java_lang_Object.equals(classType) && superKlass == null) {
throw ConstantPool.classFormatError("Class " + classType + " must have a superclass");
}
if (isInterface && !Type.java_lang_Object.equals(superKlass)) {
throw ConstantPool.classFormatError("Interface " + classType + " must extend java.lang.Object");
}
Symbol<Type>[] superInterfaces;
try (DebugCloseable closeable = PARSE_INTERFACES.scope(context.getTimers())) {
superInterfaces = parseInterfaces();
}
final ParserField[] fields;
try (DebugCloseable closeable = PARSE_FIELD.scope(context.getTimers())) {
fields = parseFields(isInterface);
}
final ParserMethod[] methods;
try (DebugCloseable closeable = PARSE_METHODS.scope(context.getTimers())) {
methods = parseMethods(isInterface);
}
final Attribute[] attributes;
try (DebugCloseable closeable = PARSE_CLASSATTR.scope(context.getTimers())) {
attributes = parseClassAttributes();
}
// Ensure there are no trailing bytes
stream.checkEndOfFile();
if (classDefinitionInfo.isHidden()) {
assert requestedClassType != null;
int futureKlassID = context.getNewKlassId();
classDefinitionInfo.initKlassID(futureKlassID);
thisKlassName = context.getNames().getOrCreate(Types.hiddenClassName(requestedClassType, futureKlassID));
thisKlassType = context.getTypes().fromName(thisKlassName);
pool = pool.patchForHiddenClass(thisKlassIndex, thisKlassName);
}
return new ParserKlass(pool, classDefinitionInfo.patchFlags(classFlags), thisKlassName, thisKlassType, superKlass, superInterfaces, methods, fields, attributes, thisKlassIndex);
}
Aggregations