< prev index next > src/hotspot/share/classfile/verifier.hpp
Print this page
/*
- * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2025, 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.
#include "runtime/handles.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/resourceHash.hpp"
+ struct NameAndSig {
+ Symbol* _name;
+ Symbol* _signature;
+
+ NameAndSig(Symbol* n, Symbol* s) : _name(n), _signature(s) {}
+ };
+
// The verifier class
class Verifier : AllStatic {
public:
enum {
STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50,
INVOKEDYNAMIC_MAJOR_VERSION = 51,
NO_RELAX_ACCESS_CTRL_CHECK_VERSION = 52,
- DYNAMICCONSTANT_MAJOR_VERSION = 55
+ DYNAMICCONSTANT_MAJOR_VERSION = 55,
+ VALUE_TYPES_MAJOR_VERSION = 67,
+ JAVA_PREVIEW_MINOR_VERSION = 65535,
};
// Verify the bytecodes for a class.
static bool verify(InstanceKlass* klass, bool should_verify_class, TRAPS);
INVALID_BYTECODE, // There was a problem with the bytecode
WRONG_TYPE, // Type value was not as expected
FLAGS_MISMATCH, // Frame flags are not assignable
BAD_CP_INDEX, // Invalid constant pool index
BAD_LOCAL_INDEX, // Invalid local index
+ BAD_STRICT_FIELDS, // Strict instance fields must be initialized before super constructor
LOCALS_SIZE_MISMATCH, // Frames have differing local counts
STACK_SIZE_MISMATCH, // Frames have different stack sizes
+ STRICT_FIELDS_MISMATCH, // Frames have incompatible uninitialized strict instance fields
STACK_OVERFLOW, // Attempt to push onto a full expression stack
STACK_UNDERFLOW, // Attempt to pop and empty expression stack
MISSING_STACKMAP, // No stackmap for this location and there should be
BAD_STACKMAP, // Format error in stackmap
+ WRONG_INLINE_TYPE, // Mismatched inline type
NO_FAULT, // No error
UNKNOWN
} FaultType;
int _bci;
return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
}
static ErrorContext bad_local_index(int bci, int index) {
return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
}
+ static ErrorContext bad_strict_fields(int bci, StackMapFrame* cur) {
+ return ErrorContext(bci, BAD_STRICT_FIELDS, TypeOrigin::frame(cur));
+ }
static ErrorContext locals_size_mismatch(
int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
}
static ErrorContext stack_size_mismatch(
int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
return ErrorContext(bci, STACK_SIZE_MISMATCH,
TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
}
+ static ErrorContext strict_fields_mismatch(
+ int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
+ return ErrorContext(bci, STRICT_FIELDS_MISMATCH,
+ TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
+ }
static ErrorContext stack_overflow(int bci, StackMapFrame* frame) {
return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
}
static ErrorContext stack_underflow(int bci, StackMapFrame* frame) {
return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
return ErrorContext(bci, MISSING_STACKMAP);
}
static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
}
+ static ErrorContext bad_inline_type(int bci, TypeOrigin type, TypeOrigin exp) {
+ return ErrorContext(bci, WRONG_INLINE_TYPE, type, exp);
+ }
bool is_valid() const { return _fault != NO_FAULT; }
int bci() const { return _bci; }
void reset_frames() {
// bytecode or loop.
bool ends_in_athrow(u4 start_bc_offset);
void verify_invoke_instructions(
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
- bool in_try_block, bool* this_uninit, VerificationType return_type,
+ bool in_try_block, bool* this_uninit,
const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS);
VerificationType get_newarray_type(u2 index, int bci, TRAPS);
void verify_anewarray(int bci, u2 index, const constantPoolHandle& cp,
StackMapFrame* current_frame, TRAPS);
int change_sig_to_verificationType(
SignatureStream* sig_type, VerificationType* inference_type);
VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
- return VerificationType::reference_type(cp->klass_name_at(index));
+ Symbol* name = cp->klass_name_at(index);
+ return VerificationType::reference_type(name);
}
// Keep a list of temporary symbols created during verification because
// their reference counts need to be decremented when the verifier object
// goes out of scope. Since these symbols escape the scope in which they're
{
Symbol* name = sig_type->as_symbol();
// Create another symbol to save as signature stream unreferences this symbol.
Symbol* name_copy = create_temporary_symbol(name);
assert(name_copy == name, "symbols don't match");
- *inference_type =
- VerificationType::reference_type(name_copy);
+ *inference_type = VerificationType::reference_type(name_copy);
return 1;
}
case T_LONG:
*inference_type = VerificationType::long_type();
*++inference_type = VerificationType::long2_type();
< prev index next >