52 using namespace cacao;
54 #define DEBUG_NAME "descriptor"
85 bool check_field_descriptor();
86 bool check_param_descriptor(
Type &dst);
87 bool check_return_descriptor();
94 bool parse_field_descriptor(
typedesc *dst);
95 bool parse_param_descriptor(
typedesc *dst);
96 bool parse_return_descriptor(
typedesc *dst);
101 bool start_param_list();
107 bool has_more_params();
122 bool check_type(
const char *descriptor_type,
Type& t);
125 bool parse_type(
const char *descriptor_type,
typedesc *t);
132 bool parse_arraytype(
Utf8String& classname,
size_t& arraydim);
134 bool skip_classname();
139 bool has_more_input()
const;
142 bool throw_error(
const char *reason, ...);
150 : pool(pool),
pos(desc.begin()), end(desc.end()) {}
155 return check_type<FORBID_VOID_TYPE | EXPECT_END_OF_INPUT>(
"field", dummy);
158 return check_type<FORBID_VOID_TYPE>(
"parameter", dst);
163 return check_type<EXPECT_END_OF_INPUT>(
"return type", dummy);
167 return parse_type<FORBID_VOID_TYPE | EXPECT_END_OF_INPUT>(
"field", dst);
170 return parse_type<FORBID_VOID_TYPE>(
"parameter", dst);
173 return parse_type<EXPECT_END_OF_INPUT>(
"return type", dst);
185 return throw_error(
"Method descriptor does not start with '('");
214 switch (parse_type<flags>(type, primtype, classname, arraydim)) {
239 switch (parse_type<flags>(type, primtype, classname, arraydim)) {
346 throw_error(
"Unexpected characters at end of descriptor");
356 const char *mark =
pos;
366 return throw_error(
"Class name is not valid UTF-8");
375 size_t array_dimension = 0;
377 const char *mark =
pos;
392 if (array_dimension > 255)
393 return throw_error(
"Too large array dimension: %lu", array_dimension);
415 return throw_error(
"Illegal type of array element '%c'", c);
420 if (classname == NULL)
421 return throw_error(
"Name is not valid utf8: '%s'", mark);
423 arraydim = array_dimension;
460 va_start(ap, reason);
473 #define CLASSREFHASH_INIT_SIZE 256
476 #define FIELDREFHASH_INIT_SIZE 256
489 descriptors_next(NULL) {}
512 LOG(
"DescriptorPool::add_class(" << name <<
")");
544 LOG(
"DescriptorPool::add_field(" << ((
void*)
this) <<
", " << desc <<
")\n");
577 LOG(
"DescriptorPool::add_method(" << ((
void*)
this) <<
", " << desc <<
")\n");
606 if (argcount > 255) {
722 td = allocate<typedesc>();
726 if (!parser.parse_field_descriptor(td))
754 LOG(
"DescriptorPool::parse_method_descriptor(" << ((
void*)
this) <<
", " << mflags <<
", " << thisclass <<
")\n");
761 if (desc[0] !=
'(') {
763 "Field descriptor used in method reference");
776 typedesc *td = allocate<typedesc>();
796 typedesc *td = allocate<typedesc>();
817 typedesc *td = allocate<typedesc>();
844 #if defined(ENABLE_JIT)
878 bool has_lock = pool_lock != NULL;
888 assert(params == NULL);
899 thisclass = td[paramcount].
classref;
902 if (paramcount > 0) {
920 if (paramcount > 0) {
931 #if defined(ENABLE_JIT)
964 assert(classrefsize);
979 assert(descriptor.
size() >= 1);
981 switch (descriptor[0]) {
1003 vm_abort(
"descriptor_to_basic_type: invalid type %c", descriptor[0]);
1020 fprintf(file,
"(typedesc *)NULL");
1028 fprintf(file,
"<class=NULL>");
1054 fprintf(file,
"(paramdesc *)NULL");
1059 fprintf(file,
"<m%d>",d->
regoff);
1062 fprintf(file,
"<r%d>",d->
regoff);
1073 fprintf(file,
"(methoddesc *)NULL");
1087 fputs(
"<NOPARAMS>",file);
Utf8String utf8_str()
get utf-8 string contents of buffer as utf8-string
bool check_type(const char *descriptor_type, Type &t)
bool parse_arraytype(Utf8String &classname, size_t &arraydim)
void get_sizes(size_t *classrefsize, size_t *descsize)
void descriptor_debug_print_paramdesc(FILE *file, paramdesc *d)
bool check_return_descriptor()
bool parse_field_descriptor(typedesc *dst)
classinfo * get_referer()
Entry & insert(const T &t)
Dummy implementation of a mutex.
bool parse_type(const char *descriptor_type, typedesc *t)
void exceptions_throw_classformaterror(classinfo *c, const char *message,...)
T * allocate(size_t size=sizeof(T))
JNIEnv jclass jobject const char * name
JNIEnv jthread jobject jclass jlong size
bool parse_param_descriptor(typedesc *dst)
void vm_abort(const char *text,...)
#define IS_2_WORD_TYPE(a)
#define CLASSREFHASH_INIT_SIZE
constant_classref * lookup_classref(Utf8String classname)
const char * descriptor_type
bool add_field(Utf8String desc)
bool check_param_descriptor(Type &dst)
bool throw_error(const char *reason,...)
throws a classformat error and returns false
bool parse_return_descriptor(typedesc *dst)
Type
Types used internally by JITTED code.
bool is_valid_name() const
void exceptions_throw_internalerror(const char *message,...)
#define MMOVE(dest, src, type, num)
static Utf8String from_utf8(const char *, size_t)
FieldrefHash fieldrefhash
Type descriptor_to_basic_type(Utf8String descriptor)
void md_param_alloc(methoddesc *md)
void params_from_paramtypes(s4 mflags)
void utf_fprint_printable_ascii(FILE *file, Utf8String u)
#define METHODDESC_NOPARAMS
#define LOG(STMT)
Analogous to DEBUG.
void md_param_alloc_native(methoddesc *md)
typedesc * parse_field_descriptor(Utf8String desc)
EntryRef find(const T &t)
ssize_t add_method(Utf8String desc)
bool parse_classname(Utf8String &classname)
uint8_t * descriptors_next
Buffer & writevf(const char *fmt, va_list ap)
constant_classref * classrefs
methoddesc * parse_method_descriptor(Utf8String desc, s4 mflags, constant_classref *thisclass)
bool check_field_descriptor()
ClassrefHash classrefhash
bool add_class(Utf8String name)
void descriptor_debug_print_typedesc(FILE *file, typedesc *d)
void descriptor_debug_print_methoddesc(FILE *file, methoddesc *d)
PrimitiveType primitivetype
constant_classref * create_classrefs(s4 *count)
DescriptorParser(DescriptorPool *pool, Utf8String desc)
#define FIELDREFHASH_INIT_SIZE
constant_classref * classref
bool has_more_input() const
void alloc_parsed_descriptors()
DescriptorPool *const pool