use of com.oracle.truffle.espresso.descriptors.Symbol.Name in project graal by oracle.
the class MethodVerifier method verifyInvokeStatic.
private void verifyInvokeStatic(int bci, OperandStack stack) {
// Check CP validity
MethodRefConstant mrc = getMethodRefConstant(bci);
// Checks versioning
if (version51OrEarlier()) {
verifyGuarantee(mrc.tag() != INTERFACE_METHOD_REF, "invokeStatic refers to an interface method with classfile version " + majorVersion);
}
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));
if (!(returnOp == Void)) {
stack.push(returnOp);
}
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Name 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.Name in project graal by oracle.
the class JImageLibrary method findLocation.
private long findLocation(TruffleObject jimage, TruffleObject sizePtr, String name) {
try (RawBuffer nameBuffer = RawBuffer.getNativeString(name)) {
TruffleObject namePtr = nameBuffer.pointer();
long location = (long) execute(findResource, jimage, emptyStringBuffer.pointer(), versionBuffer.pointer(), namePtr, sizePtr);
if (location != 0) {
// found.
return location;
}
String pkg = packageFromName(name);
if (pkg == null) {
return 0;
}
if (!getContext().modulesInitialized()) {
location = (long) execute(findResource, jimage, javaBaseBuffer.pointer(), versionBuffer.pointer(), namePtr, sizePtr);
if (location != 0 || !getContext().metaInitialized()) {
// finding certain classes in java.base (/ex: sun/misc/Unsafe).
return location;
}
TruffleObject moduleName;
try (RawBuffer pkgBuffer = RawBuffer.getNativeString(pkg)) {
moduleName = (TruffleObject) execute(packageToModule, jimage, pkgBuffer.pointer());
}
if (uncached.isNull(moduleName)) {
return 0;
}
return (long) execute(findResource, jimage, moduleName, versionBuffer.pointer(), namePtr, sizePtr);
} else {
Symbol<Name> pkgSymbol = getNames().lookup(pkg);
if (pkgSymbol == null) {
return 0;
}
PackageEntry pkgEntry = getRegistries().getBootClassRegistry().packages().lookup(pkgSymbol);
if (pkgEntry == null) {
return 0;
}
Symbol<Name> moduleName = pkgEntry.module().getName();
if (moduleName == Name.java_base) {
return (long) execute(findResource, jimage, javaBaseBuffer.pointer(), versionBuffer.pointer(), namePtr, sizePtr);
} else {
String nameAsString = moduleName == null ? "" : moduleName.toString();
try (RawBuffer moduleNameBuffer = RawBuffer.getNativeString(nameAsString)) {
return (long) execute(findResource, jimage, moduleNameBuffer.pointer(), versionBuffer.pointer(), namePtr, sizePtr);
}
}
}
}
}
use of com.oracle.truffle.espresso.descriptors.Symbol.Name 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.Name in project graal by oracle.
the class ClassfileParser method parseMethod.
private ParserMethod parseMethod(boolean isInterface) {
int methodFlags = stream.readU2();
int nameIndex = stream.readU2();
int signatureIndex = stream.readU2();
final Symbol<Name> name;
final Symbol<Signature> signature;
int attributeCount;
Attribute[] methodAttributes;
int extraFlags = methodFlags;
boolean isClinit = false;
boolean isInit = false;
try (DebugCloseable closeable = METHOD_INIT.scope(context.getTimers())) {
try (DebugCloseable nameCheck = NAME_CHECK.scope(context.getTimers())) {
pool.utf8At(nameIndex).validateMethodName(true);
name = pool.symbolAt(nameIndex, "method name");
if (name.equals(Name._clinit_)) {
// ACC_STRICT flag.
if (majorVersion < JAVA_7_VERSION) {
// Backwards compatibility.
methodFlags = ACC_STATIC;
} else if ((methodFlags & ACC_STATIC) == ACC_STATIC) {
methodFlags &= (ACC_STRICT | ACC_STATIC);
} else if (context.getJavaVersion().java9OrLater()) {
throw ConstantPool.classFormatError("Method <clinit> is not static.");
}
// extraFlags = INITIALIZER | methodFlags;
isClinit = true;
} else if (name.equals(Name._init_)) {
if (isInterface) {
throw ConstantPool.classFormatError("Method <init> is not valid in an interface.");
}
isInit = true;
}
}
final boolean isStatic = Modifier.isStatic(extraFlags);
verifyMethodFlags(methodFlags, isInterface, isInit, isClinit, majorVersion);
/*
* A method is a class or interface initialization method if all of the following are
* true:
*
* It has the special name <clinit>.
*
* It is void (4.3.3). (checked earlier)
*
* In a class file whose version number is 51.0 or above, the method has its ACC_STATIC
* flag set and takes no arguments (4.6).
*/
try (DebugCloseable signatureCheck = SIGNATURE_CHECK.scope(context.getTimers())) {
// Checks for void method if init or clinit.
/*
* Obtain slot number for the signature. Forces a validation, but better in startup
* than going twice through the sequence, once for validation, once for slots.
*/
int slots = pool.utf8At(signatureIndex).validateSignatureGetSlots(isInit || isClinit);
signature = Signatures.check(pool.symbolAt(signatureIndex, "method descriptor"));
if (isClinit && majorVersion >= JAVA_7_VERSION) {
// Checks clinit takes no arguments.
if (!signature.equals(Signature._void)) {
throw ConstantPool.classFormatError("Method <clinit> has invalid signature: " + signature);
}
}
if (slots + (isStatic ? 0 : 1) > 255) {
throw ConstantPool.classFormatError("Too many arguments in method signature: " + signature);
}
if (name.equals(Name.finalize) && signature.equals(Signature._void) && !Modifier.isStatic(methodFlags) && !Type.java_lang_Object.equals(classType)) {
// This class has a finalizer method implementation (ignore for
// java.lang.Object).
classFlags |= ACC_FINALIZER;
}
}
attributeCount = stream.readU2();
methodAttributes = spawnAttributesArray(attributeCount);
}
CodeAttribute codeAttribute = null;
Attribute checkedExceptions = null;
Attribute runtimeVisibleAnnotations = null;
CommonAttributeParser commonAttributeParser = new CommonAttributeParser(InfoType.Method);
MethodParametersAttribute methodParameters = null;
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 (attributeName.equals(Name.Code)) {
if (codeAttribute != null) {
throw ConstantPool.classFormatError("Duplicate Code attribute");
}
try (DebugCloseable code = CODE_PARSE.scope(context.getTimers())) {
methodAttributes[i] = codeAttribute = parseCodeAttribute(attributeName);
}
} else if (attributeName.equals(Name.Exceptions)) {
if (checkedExceptions != null) {
throw ConstantPool.classFormatError("Duplicate Exceptions attribute");
}
methodAttributes[i] = checkedExceptions = parseExceptions(attributeName);
} else if (attributeName.equals(Name.Synthetic)) {
methodFlags |= ACC_SYNTHETIC;
methodAttributes[i] = checkedExceptions = new Attribute(attributeName, null);
} else if (majorVersion >= JAVA_1_5_VERSION) {
if (attributeName.equals(Name.RuntimeVisibleAnnotations)) {
if (runtimeVisibleAnnotations != null) {
throw ConstantPool.classFormatError("Duplicate RuntimeVisibleAnnotations attribute");
}
// Check if java.lang.invoke.LambdaForm.Compiled is present here.
byte[] data = stream.readByteArray(attributeSize);
ClassfileStream subStream = new ClassfileStream(data, this.classfile);
int count = subStream.readU2();
for (int j = 0; j < count; j++) {
int typeIndex = parseAnnotation(subStream);
Utf8Constant constant = pool.utf8At(typeIndex, "annotation type");
// Validation of the type is done at runtime by guest java code.
Symbol<Type> annotType = constant.value();
if (Type.java_lang_invoke_LambdaForm$Compiled.equals(annotType)) {
methodFlags |= ACC_LAMBDA_FORM_COMPILED;
} else if (Type.java_lang_invoke_LambdaForm$Hidden.equals(annotType) || Type.jdk_internal_vm_annotation_Hidden.equals(annotType)) {
methodFlags |= ACC_HIDDEN;
} else if (Type.sun_reflect_CallerSensitive.equals(annotType) || Type.jdk_internal_reflect_CallerSensitive.equals(annotType)) {
methodFlags |= ACC_CALLER_SENSITIVE;
}
}
methodAttributes[i] = runtimeVisibleAnnotations = new Attribute(attributeName, data);
} else if (attributeName.equals(Name.MethodParameters)) {
if (methodParameters != null) {
throw ConstantPool.classFormatError("Duplicate MethodParameters attribute");
}
methodAttributes[i] = methodParameters = parseMethodParameters(attributeName);
} else {
Attribute attr = commonAttributeParser.parseCommonAttribute(attributeName, attributeSize);
// stream.skip(attributeSize);
methodAttributes[i] = attr == null ? new Attribute(attributeName, stream.readByteArray(attributeSize)) : attr;
}
} else {
// stream.skip(attributeSize);
methodAttributes[i] = new Attribute(attributeName, stream.readByteArray(attributeSize));
}
final int distance = stream.getPosition() - startPosition;
if (attributeSize != distance) {
final String message = "Invalid attribute_length for " + attributeName + " attribute (reported " + attributeSize + " != parsed " + distance + ")";
throw ConstantPool.classFormatError(message);
}
}
if (Modifier.isAbstract(methodFlags) || Modifier.isNative(methodFlags)) {
if (codeAttribute != null) {
throw ConstantPool.classFormatError("Code attribute supplied for native or abstract method");
}
} else {
if (codeAttribute == null) {
throw ConstantPool.classFormatError("Missing Code attribute");
}
}
if (classDefinitionInfo.isHidden()) {
methodFlags |= ACC_HIDDEN;
}
return ParserMethod.create(methodFlags, name, signature, methodAttributes);
}
Aggregations