CACAO
descriptor.cpp
Go to the documentation of this file.
1 /* src/vm/descriptor.cpp - checking and parsing of field / method descriptors
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #include "vm/descriptor.hpp"
26 #include "config.h" // for ENABLE_JIT
27 
28 #include <cassert> // for assert
29 #include <cstdarg> // for va_end, va_list, va_start
30 
31 #include "mm/memory.hpp" // for MNEW, MMOVE
32 
33 #include "threads/mutex.hpp" // for Mutex
34 
35 #include "toolbox/OStream.hpp" // for OStream
36 #include "toolbox/buffer.hpp" // for Buffer
37 #include "toolbox/logging.hpp" // for LOG
38 
39 #include "vm/exceptions.hpp"
40 #include "vm/global.hpp" // for Type::TYPE_ADR, etc
41 #include "vm/options.hpp"
42 #include "vm/primitive.hpp" // for PrimitiveType, etc
43 #include "vm/references.hpp" // for constant_classref
44 #include "vm/types.hpp" // for u4, u1, s4, s2, u2
45 #include "vm/utf8.hpp" // for Utf8String, operator<<, etc
46 #include "vm/vm.hpp" // for vm_abort
47 
48 #include "vm/jit/abi.hpp" // for md_param_alloc, etc
49 
50 struct classinfo;
51 
52 using namespace cacao;
53 
54 #define DEBUG_NAME "descriptor"
55 
56 
57 /***
58  *
59  * Field & method descriptor parsing
60  *
61  * See JVM Spec §4.3.2 (Field Descriptors) and §4.3.3 (Method Descriptors)
62  *
63  * All methods return true on success and throw an exception on error.
64  * They also check if the parsed type is valid for its position, for example
65  * a field type can't be void but a return type can.
66  *
67  * Calling a check or parse method consumes the input.
68  * In the following example the call to parse_field_descriptor() will fail
69  * because check_field_descriptor() has consumed the whole descriptor.
70  * @code
71  * DescriptorParser p(pool, Utf8String::from_utf8("J"));
72  * if (!p.check_field_descriptor())
73  * return false;
74  * if (!p.parse_field_descriptor(&t))
75  * return false;
76  * @endcode
77  */
80 
81  /***
82  * Check if descriptor is valid.
83  * Any class references in descriptor will be added to pool
84  */
85  bool check_field_descriptor();
86  bool check_param_descriptor(Type &dst);
87  bool check_return_descriptor();
88 
89  /***
90  * Parse descriptor into typedesc.
91  * Descriptor must have previously been checked with check_*_descriptor()
92  * All class references are looked up in pool.
93  */
94  bool parse_field_descriptor(typedesc *dst);
95  bool parse_param_descriptor(typedesc *dst);
96  bool parse_return_descriptor(typedesc *dst);
97 
98  /***
99  * Start parsing a method descriptors parameter list
100  */
101  bool start_param_list();
102 
103  /***
104  * Check if the parameter list we are currently parsing
105  * has more parameters to parse.
106  */
107  bool has_more_params();
108 private:
109  enum ParserFlag {
111  EXPECT_END_OF_INPUT
112  };
113 
114  enum ParseResult {
117  REFERENCE_TYPE
118  };
119 
120 
121  template<int flags>
122  bool check_type(const char *descriptor_type, Type& t);
123 
124  template<int flags>
125  bool parse_type(const char *descriptor_type, typedesc *t);
126 
127  template<int flags>
128  ParseResult parse_type(Type& t, PrimitiveType& p,
129  Utf8String& classname, size_t& arraydim);
130 
131  bool parse_classname(Utf8String& classname);
132  bool parse_arraytype(Utf8String& classname, size_t& arraydim);
133 
134  bool skip_classname();
135 
136  bool read(char&);
137  void unread();
138 
139  bool has_more_input() const;
140 
141  /// throws a classformat error and returns false
142  bool throw_error(const char *reason, ...);
143 
145  const char *descriptor_type; // what kind of descriptor we are currently parsing
146  const char *pos, *end; // text of descriptor
147 };
148 
150  : pool(pool), pos(desc.begin()), end(desc.end()) {}
151 
153  Type dummy;
154 
155  return check_type<FORBID_VOID_TYPE | EXPECT_END_OF_INPUT>("field", dummy);
156 }
158  return check_type<FORBID_VOID_TYPE>("parameter", dst);
159 }
161  Type dummy;
162 
163  return check_type<EXPECT_END_OF_INPUT>("return type", dummy);
164 }
165 
167  return parse_type<FORBID_VOID_TYPE | EXPECT_END_OF_INPUT>("field", dst);
168 }
170  return parse_type<FORBID_VOID_TYPE>("parameter", dst);
171 }
173  return parse_type<EXPECT_END_OF_INPUT>("return type", dst);
174 }
175 
177  descriptor_type = "method";
178 
179  char c = 0;
180 
181  if (!read(c))
182  return false;
183 
184  if (c != '(')
185  return throw_error("Method descriptor does not start with '('");
186 
187  return true;
188 }
189 
191  if (!has_more_input())
192  return false;
193  if (*pos == ')') {
194  pos++;
195  return false;
196  }
197 
198  return true;
199 }
200 
201 inline bool DescriptorParser::has_more_input() const {
202  return pos != end;
203 }
204 
205 template<int flags>
206 inline bool DescriptorParser::check_type(const char *descriptor_type, Type& dst) {
207  this->descriptor_type = descriptor_type;
208 
209  Type type;
210  PrimitiveType primtype;
211  Utf8String classname;
212  size_t arraydim = 0;
213 
214  switch (parse_type<flags>(type, primtype, classname, arraydim)) {
215  case PARSE_ERROR:
216  return false;
217  case PRIMITIVE_TYPE:
218  dst = type;
219  return true;
220  case REFERENCE_TYPE:
221  // descriptor is array or class type
222  dst = type;
223  return pool->add_class(classname);
224  default:
225  assert(false);
226  return false;
227  }
228 }
229 
230 template<int flags>
231 inline bool DescriptorParser::parse_type(const char *descriptor_type, typedesc *dst) {
232  this->descriptor_type = descriptor_type;
233 
234  Type type = TYPE_INT;
235  PrimitiveType primtype = PRIMITIVETYPE_INT;
236  Utf8String classname;
237  size_t arraydim = 0;
238 
239  switch (parse_type<flags>(type, primtype, classname, arraydim)) {
240  case PARSE_ERROR:
241  return false;
242  case PRIMITIVE_TYPE:
243  dst->classref = NULL;
244  dst->type = type;
245  dst->primitivetype = primtype;
246  dst->arraydim = 0;
247  return true;
248  case REFERENCE_TYPE:
249  dst->classref = pool->lookup_classref(classname);
250  dst->type = TYPE_ADR;
252  dst->arraydim = arraydim;
253  return true;
254  default:
255  assert(false);
256  return false;
257  }
258 }
259 
260 template<int flags>
262  PrimitiveType& p,
263  Utf8String& classname,
264  size_t& arraydim) {
265  ParseResult result;
266  char c = 0;
267 
268  if (!read(c))
269  return PARSE_ERROR;
270 
271  switch (c) {
272  case 'B':
273  t = TYPE_INT;
274  p = PRIMITIVETYPE_BYTE;
275  result = PRIMITIVE_TYPE;
276  break;
277  case 'C':
278  t = TYPE_INT;
279  p = PRIMITIVETYPE_CHAR;
280  result = PRIMITIVE_TYPE;
281  break;
282  case 'D':
283  t = TYPE_DBL;
285  result = PRIMITIVE_TYPE;
286  break;
287  case 'F':
288  t = TYPE_FLT;
290  result = PRIMITIVE_TYPE;
291  break;
292  case 'I':
293  t = TYPE_INT;
294  p = PRIMITIVETYPE_INT;
295  result = PRIMITIVE_TYPE;
296  break;
297  case 'J':
298  t = TYPE_LNG;
299  p = PRIMITIVETYPE_LONG;
300  result = PRIMITIVE_TYPE;
301  break;
302  case 'S':
303  t = TYPE_INT;
305  result = PRIMITIVE_TYPE;
306  break;
307  case 'Z':
308  t = TYPE_INT;
310  result = PRIMITIVE_TYPE;
311  break;
312  case 'V':
313  if (flags & FORBID_VOID_TYPE) {
314  throw_error("Type void is illegal");
315  return PARSE_ERROR;
316  }
317 
318  t = TYPE_VOID;
319  p = PRIMITIVETYPE_VOID;
320  result = PRIMITIVE_TYPE;
321  break;
322 
323  case 'L': // object (L<classname>;)
324  if (!parse_classname(classname))
325  return PARSE_ERROR;
326 
327  t = TYPE_ADR;
328  arraydim = 0;
329  result = REFERENCE_TYPE;
330  break;
331  case '[': // array type
332  unread(); // parse_arraytype counts the '['
333 
334  if (!parse_arraytype(classname, arraydim))
335  return PARSE_ERROR;
336 
337  t = TYPE_ADR;
338  result = REFERENCE_TYPE;
339  break;
340  default:
341  throw_error("Illegal character '%c'", c);
342  return PARSE_ERROR;
343  }
344 
345  if ((flags & EXPECT_END_OF_INPUT) && has_more_input()) {
346  throw_error("Unexpected characters at end of descriptor");
347  return PARSE_ERROR;
348  }
349 
350  return result;
351 }
352 
354  // find end of classname
355 
356  const char *mark = pos;
357 
358  if (!skip_classname())
359  return false;
360 
361  // utf8 string from classname
362 
363  Utf8String str = Utf8String::from_utf8(mark, pos - mark - 1);
364 
365  if (str == NULL)
366  return throw_error("Class name is not valid UTF-8");
367 
368  // done
369 
370  classname = str;
371  return true;
372 }
373 
374 inline bool DescriptorParser::parse_arraytype(Utf8String& classname, size_t& arraydim) {
375  size_t array_dimension = 0;
376 
377  const char *mark = pos;
378 
379  char c = 0;
380 
381  // skip leading '['
382 
383  while (true) {
384  if (!read(c))
385  return false;
386  if (c != '[')
387  break;
388 
389  array_dimension++;
390  }
391 
392  if (array_dimension > 255)
393  return throw_error("Too large array dimension: %lu", array_dimension);
394 
395  // check if element type is valid
396 
397  switch (c) {
398  case 'B': // primitive type
399  case 'C':
400  case 'D':
401  case 'F':
402  case 'I':
403  case 'J':
404  case 'S':
405  case 'Z':
406  break;
407 
408  case 'L': // object (L<classname>;)
409  if(!skip_classname())
410  return false;
411 
412  break;
413 
414  default:
415  return throw_error("Illegal type of array element '%c'", c);
416  }
417 
418  classname = Utf8String::from_utf8(mark, pos - mark);
419 
420  if (classname == NULL)
421  return throw_error("Name is not valid utf8: '%s'", mark);
422 
423  arraydim = array_dimension;
424 
425  return true;
426 }
427 
429  // classname is delimited by 'L' and ';'
430  // but at this point the 'L' was already consumed
431 
432  while (true) {
433  char c = 0;
434 
435  if (!read(c))
436  return false;
437  if (c == ';')
438  return true;
439  }
440 }
441 
442 inline bool DescriptorParser::read(char& c) {
443  if (pos == end)
444  return throw_error("Truncated descriptor");
445 
446  c = *pos++;
447  return true;
448 }
449 
451  pos--;
452 }
453 
454 inline bool DescriptorParser::throw_error(const char *reason, ...) {
455  assert(descriptor_type);
456 
457  Buffer<> buf;
458  va_list ap;
459 
460  va_start(ap, reason);
461  buf.write("Invalid ").write(descriptor_type).write(" descriptor: ").writevf(reason, ap);
462  va_end(ap);
463 
465  return false;
466 }
467 
468 //******************************************************************************
469 // Descriptor pool
470 //******************************************************************************
471 
472 // initial number of entries for the classrefhash of a descriptor pool
473 #define CLASSREFHASH_INIT_SIZE 256
474 
475 // initial number of entries for the fieldrefhash of a descriptor pool
476 #define FIELDREFHASH_INIT_SIZE 256
477 
478 
479 DescriptorPool::DescriptorPool(classinfo *referer) : classrefhash(CLASSREFHASH_INIT_SIZE),
480  fieldrefhash(FIELDREFHASH_INIT_SIZE),
481  referer(referer),
482  fieldcount(0),
483  methodcount(0),
484  paramcount(0),
485  descriptorsize(0),
486  classrefs(NULL),
487  mutex(new Mutex()),
488  descriptors(NULL),
489  descriptors_next(NULL) {}
490 
491 /***
492  * Allocate an object from the descriptor pools private block of memory.
493  * This function performs no checks, you can only allocate objects you have
494  * previously added via add_field or add_method.
495  */
496 template<typename T>
498  T *t = (T*) descriptors_next;
499 
501 
502  return t;
503 }
504 
505 
506 /***
507  * Add the given class reference to the pool
508  *
509  * @return false iff an exception was thrown.
510 */
512  LOG("DescriptorPool::add_class(" << name << ")");
513 
514  assert(name);
515 
516  /* find a place in the hashtable */
517 
518  ClassrefHash::EntryRef ref = classrefhash.find(name);
519 
520  if (ref)
521  return true; // classname was already present
522 
523  /* check if the name is a valid classname */
524 
525  if (!name.is_valid_name()) {
526  exceptions_throw_classformaterror(referer, "Invalid class name");
527  return false; /* exception */
528  }
529 
530  /* XXX check maximum array dimension */
531 
532  classrefhash.insert(ref, name, classrefhash.size());
533  return true;
534 }
535 
536 
537 /***
538  * Check the given descriptor and add it to the pool
539  *
540  * @param desc the field descriptor to add.
541  * @return false iff an exception has been thrown
542  */
544  LOG("DescriptorPool::add_field(" << ((void*) this) << ", " << desc << ")\n");
545 
546  // check if field descriptor was already in table
547 
548  FieldrefHash::EntryRef ref = fieldrefhash.find(desc);
549 
550  if (ref)
551  return true;
552 
553  // check the descriptor
554 
555  DescriptorParser parser(this, desc);
556 
557  if (!parser.check_field_descriptor())
558  return false;
559 
560  // add the descriptor to the pool
561 
562  fieldrefhash.insert(ref, desc, (typedesc*) NULL);
563 
564  // done
565 
566  fieldcount++;
567  return true;
568 }
569 
570 /***
571  * Check the given descriptor and add it to the pool
572  *
573  * @param desc the method descriptor to add.
574  * @return false iff an exception has been thrown
575  */
577  LOG("DescriptorPool::add_method(" << ((void*) this) << ", " << desc << ")\n");
578 
579  assert(desc);
580 
581  // check the descriptor
582 
583  DescriptorParser parser(this, desc);
584 
585  size_t argcount = 0;
586 
587  // check parameters
588 
589  if (!parser.start_param_list())
590  return -1;
591 
592  while (parser.has_more_params()) {
593  // We cannot count the `this' argument here because
594  // we don't know if the method is static.
595 
596  paramcount++;
597 
598  Type type;
599 
600  if (!parser.check_param_descriptor(type))
601  return -1;
602 
603  argcount += IS_2_WORD_TYPE(type) ? 2 : 1;
604  }
605 
606  if (argcount > 255) {
607  exceptions_throw_classformaterror(referer, "Too many arguments in signature");
608  return -1;
609  }
610 
611  // check return type
612 
613  if (!parser.check_return_descriptor())
614  return -1;
615 
616  // done
617 
618  methodcount++;
619  return argcount;
620 }
621 
622 
623 /***
624  * Create a table containing all the classrefs which were added to the pool
625  *
626  * @param[out] count if count is non-NULL, this is set to the number
627  * of classrefs in the table
628  * @return a pointer to the constant_classref table
629  */
631 {
632  size_t nclasses;
633 
634  nclasses = classrefhash.size();
635  classrefs = MNEW(constant_classref,nclasses);
636 
637  // fill the constant_classref structs
638 
639  for (ClassrefHash::Iterator it = classrefhash.begin(), end = classrefhash.end(); it != end; ++it) {
640  new (classrefs + it->value()) constant_classref(referer, it->key());
641  }
642 
643  if (count)
644  *count = nclasses;
645 
646  return classrefs;
647 }
648 
649 
650 /***
651  * Return the constant_classref for the given class name
652  *
653  * @param classname name of the class to look up
654  * @return a pointer to the constant_classref, or
655  * NULL if an exception has been thrown
656  */
658 {
659  assert(classrefs);
660  assert(classname);
661 
662  if (ClassrefHash::EntryRef ref = classrefhash.find(classname)) {
663  return classrefs + ref->value();
664  } else {
665  exceptions_throw_internalerror("Class reference not found in descriptor pool");
666  return NULL;
667  }
668 }
669 
670 
671 /***
672  * Allocate space for the parsed descriptors
673  *
674  * @note
675  * This function must be called after all descriptors have been added
676  * with DescriptorPool::add.
677  */
679  /* TWISTI: paramcount + 1: we don't know if the method is static or */
680  /* not, i have no better solution yet. */
681 
682  size_t size = fieldcount * sizeof(typedesc)
683  + methodcount * (sizeof(methoddesc) - sizeof(typedesc))
684  + paramcount * sizeof(typedesc)
685  + methodcount * sizeof(typedesc); // possible `this' pointer
686 
688 
689  if (size) {
690  descriptors = MNEW(u1, size);
692  }
693 }
694 
695 
696 /***
697  * Parse the given field descriptor
698  *
699  * @param pool the descriptor_pool
700  * @param desc the field descriptor
701  * @return a pointer to the parsed field descriptor, or
702  * NULL if an exception has been thrown
703  *
704  * @note
705  * DescriptorPool::alloc_parsed_descriptors must be called (once)
706  * before this function is used.
707  */
709  assert(descriptors);
710  assert(descriptors_next);
711 
712  // lookup the descriptor in the hashtable
713 
714  FieldrefHash::EntryRef ref = fieldrefhash.find(desc);
715 
716  assert(ref);
717 
718  typedesc *td = ref->value();
719 
720  if (!td) {
721  // field has been parsed yet.
722  td = allocate<typedesc>();
723 
724  DescriptorParser parser(this, desc);
725 
726  if (!parser.parse_field_descriptor(td))
727  return NULL;
728 
729  ref->value() = td;
730  }
731 
732  return td;
733 }
734 
735 
736 /***
737  * Parse the given method descriptor
738  *
739  * @param desc the method descriptor
740  * @param mflags the method flags
741  * @param thisclass classref to the class containing the method.
742  * This is ignored if mflags contains ACC_STATIC.
743  * The classref is stored for inserting the 'this' argument.
744  * @return a pointer to the parsed method descriptor,
745  * or NULL if an exception has been thrown
746  *
747  * @note
748  * descriptor_pool::alloc_parsed_descriptors must be called
749  * (once) before this function is used.
750  */
752  s4 mflags,
753  constant_classref *thisclass) {
754  LOG("DescriptorPool::parse_method_descriptor(" << ((void*) this) << ", " << mflags << ", " << thisclass << ")\n");
755 
756  assert(descriptors);
757  assert(descriptors_next);
758 
759  // check that it is a method descriptor
760 
761  if (desc[0] != '(') {
763  "Field descriptor used in method reference");
764  return NULL;
765  }
766 
767  methoddesc *md = allocate<methoddesc>(offsetof(methoddesc, paramtypes));
768  md->pool_lock = mutex;
769 
770  s2 paramcount = 0;
771  s2 paramslots = 0;
772 
773  // count the `this' pointer
774 
775  if ((mflags != ACC_UNDEF) && !(mflags & ACC_STATIC)) {
776  typedesc *td = allocate<typedesc>();
777 
778  td->type = TYPE_ADR;
779  td->arraydim = 0;
780  td->classref = thisclass;
781 
782  paramcount++;
783  paramslots++;
784  }
785 
786  // parse parameters
787 
788  DescriptorParser parser(this, desc);
789 
790  if (!parser.start_param_list())
791  return NULL;
792 
793  while (parser.has_more_params()) {
794  // parse a parameter type
795 
796  typedesc *td = allocate<typedesc>();
797 
798  if (!parser.parse_param_descriptor(td))
799  return NULL;
800 
801  if (IS_2_WORD_TYPE(td->type))
802  paramslots++;
803 
804  paramcount++;
805  paramslots++;
806  }
807 
808  md->paramcount = paramcount;
809  md->paramslots = paramslots;
810 
811  // Skip possible `this' pointer in paramtypes array to allow a possible
812  // memory move later in parse.
813  // We store the thisclass reference, so we can later correctly fill in
814  // the parameter slot of the 'this' argument.
815 
816  if (mflags == ACC_UNDEF) {
817  typedesc *td = allocate<typedesc>();
818 
819  td->classref = thisclass;
820  }
821 
822  // parse return type
823 
824  if (!parser.parse_return_descriptor(&md->returntype))
825  return NULL;
826 
827  // If mflags != ACC_UNDEF we parse a real loaded method, so do
828  // param prealloc. Otherwise we do this in stack analysis.
829 
830  if (mflags != ACC_UNDEF) {
831  if (md->paramcount > 0) {
832  // allocate memory for params
833 
834  md->params = MNEW(paramdesc, md->paramcount);
835  } else {
837  }
838 
839  // fill the paramdesc
840  // md_param_alloc has to be called if md->paramcount == 0,
841  // too, so it can make the reservation for the Linkage Area,
842  // Return Register...
843 
844 #if defined(ENABLE_JIT)
845  // As builtin-functions are native functions, we have
846  // to pre-allocate for the native ABI.
847 
848  if (mflags & ACC_METHOD_BUILTIN)
850  else
851  md_param_alloc(md);
852 #endif
853 
854  // params already initialized; no need to lock
855  md->pool_lock = NULL;
856  } else {
857  // params will be allocated later by
858  // methoddesc::params_from_paramtypes if necessary
859 
860  md->params = NULL;
861  }
862 
863  return md;
864 }
865 
866 /***
867  * Create the paramdescs for a method descriptor. This function is
868  * called when we know whether the method is static or not. This
869  * function does nothing if md->params != NULL (checked atomically).
870  *
871  * @param mflags the ACC_* access flags of the method. Only the
872  * ACC_STATIC bit is checked.
873  * The value ACC_UNDEF is NOT allowed.
874  *
875  * @post parms != NULL
876  */
878  bool has_lock = pool_lock != NULL;
879 
880  if (pool_lock)
881  pool_lock->lock();
882  if (params) {
883  if (has_lock)
884  pool_lock->unlock();
885  return;
886  }
887 
888  assert(params == NULL);
889  assert(mflags != ACC_UNDEF);
890 
891  typedesc *td = paramtypes;
892 
893  /* check for `this' pointer */
894 
895  if (!(mflags & ACC_STATIC)) {
896  constant_classref *thisclass;
897 
898  /* fetch class reference from reserved param slot */
899  thisclass = td[paramcount].classref;
900  assert(thisclass);
901 
902  if (paramcount > 0) {
903  /* shift param types by 1 argument */
904  MMOVE(td + 1, td, typedesc, paramcount);
905  }
906 
907  /* fill in first argument `this' */
908 
909  td->type = TYPE_ADR;
911  td->arraydim = 0;
912  td->classref = thisclass;
913 
914  paramcount++;
915  paramslots++;
916  }
917 
918  // if the method has params, process them
919 
920  if (paramcount > 0) {
921  // allocate memory for params
922  params = MNEW(paramdesc, paramcount);
923  } else {
924  params = METHODDESC_NOPARAMS;
925  }
926 
927  // fill the paramdesc
928  // md_param_alloc has to be called if md->paramcount == 0, too, so
929  // it can make the reservation for the Linkage Area, Return Register, ...
930 
931 #if defined(ENABLE_JIT)
932  // As builtin-functions are native functions, we have to
933  // pre-allocate for the native ABI.
934 
935  if (mflags & ACC_METHOD_BUILTIN)
936  md_param_alloc_native(this);
937  else
938  md_param_alloc(this);
939 #endif
940 
941  if (has_lock)
942  pool_lock->unlock();
943 }
944 
946  return referer;
947 }
948 
949 /***
950  * Get the sizes of the class reference table and the parsed descriptors
951  *
952  * @param[out] classrefsize set to size of the class reference table
953  * @param[out] descsize set to size of the parsed descriptors
954  *
955  * @note
956  * This function may only be called after both
957  * descriptor_pool::create_classrefs, and
958  * descriptor_pool::alloc_parsed_descriptors
959  * have been called.
960  */
961 void DescriptorPool::get_sizes(size_t *classrefsize, size_t *descsize) {
962  assert((!fieldcount && !methodcount) || descriptors);
963  assert(classrefs);
964  assert(classrefsize);
965  assert(descsize);
966 
967  *classrefsize = classrefhash.size() * sizeof(constant_classref);
968  *descsize = descriptorsize;
969 }
970 
971 
972 /***
973  * Return the basic type to use for a value with this descriptor.
974  *
975  * @pre This function assumes that the descriptor has passed
976  * DescriptorPool::add_field checks and that it does not start with '('.
977  */
979  assert(descriptor.size() >= 1);
980 
981  switch (descriptor[0]) {
982  case 'Z':
983  case 'B':
984  case 'C':
985  case 'S':
986  case 'I':
987  return TYPE_INT;
988 
989  case 'J':
990  return TYPE_LNG;
991 
992  case 'F':
993  return TYPE_FLT;
994 
995  case 'D':
996  return TYPE_DBL;
997 
998  case 'L':
999  case '[':
1000  return TYPE_ADR;
1001 
1002  default:
1003  vm_abort("descriptor_to_basic_type: invalid type %c", descriptor[0]);
1004  return TYPE_VOID;
1005  }
1006 }
1007 
1008 
1009 /****************************************************************************/
1010 /* DEBUG HELPERS */
1011 /****************************************************************************/
1012 
1013 /***
1014  * Print the given typedesc to the given stream
1015  */
1017  int ch;
1018 
1019  if (!d) {
1020  fprintf(file,"(typedesc *)NULL");
1021  return;
1022  }
1023 
1024  if (d->type == TYPE_ADR) {
1025  if (d->classref)
1027  else
1028  fprintf(file,"<class=NULL>");
1029  }
1030  else {
1031  switch (d->primitivetype) {
1032  case PRIMITIVETYPE_INT : ch='I'; break;
1033  case PRIMITIVETYPE_CHAR : ch='C'; break;
1034  case PRIMITIVETYPE_BYTE : ch='B'; break;
1035  case PRIMITIVETYPE_SHORT : ch='S'; break;
1036  case PRIMITIVETYPE_BOOLEAN: ch='Z'; break;
1037  case PRIMITIVETYPE_LONG : ch='J'; break;
1038  case PRIMITIVETYPE_FLOAT : ch='F'; break;
1039  case PRIMITIVETYPE_DOUBLE : ch='D'; break;
1040  case PRIMITIVETYPE_VOID : ch='V'; break;
1041  default : ch='!';
1042  }
1043  fputc(ch,file);
1044  }
1045  if (d->arraydim)
1046  fprintf(file,"[%d]",d->arraydim);
1047 }
1048 
1049 /***
1050  * Print the given paramdesc to the given stream
1051  */
1053  if (!d) {
1054  fprintf(file,"(paramdesc *)NULL");
1055  return;
1056  }
1057 
1058  if (d->inmemory) {
1059  fprintf(file,"<m%d>",d->regoff);
1060  }
1061  else {
1062  fprintf(file,"<r%d>",d->regoff);
1063  }
1064 }
1065 
1066 /***
1067  * Print the given methoddesc to the given stream
1068  */
1070  int i;
1071 
1072  if (!d) {
1073  fprintf(file,"(methoddesc *)NULL");
1074  return;
1075  }
1076 
1077  fputc('(',file);
1078  for (i=0; i<d->paramcount; ++i) {
1079  if (i)
1080  fputc(',',file);
1082  if (d->params) {
1084  }
1085  }
1086  if (d->params == METHODDESC_NOPARAMS)
1087  fputs("<NOPARAMS>",file);
1088  fputc(')',file);
1090 }
1091 
1092 
1093 /*
1094  * These are local overrides for various environment variables in Emacs.
1095  * Please do not remove this and leave it at the end of the file, where
1096  * Emacs will automagically detect them.
1097  * ---------------------------------------------------------------------
1098  * Local variables:
1099  * mode: c++
1100  * indent-tabs-mode: t
1101  * c-basic-offset: 4
1102  * tab-width: 4
1103  * End:
1104  * vim:noexpandtab:sw=4:ts=4:
1105  */
Utf8String utf8_str()
get utf-8 string contents of buffer as utf8-string
Definition: buffer.hpp:506
bool check_type(const char *descriptor_type, Type &t)
Definition: descriptor.cpp:206
bool parse_arraytype(Utf8String &classname, size_t &arraydim)
Definition: descriptor.cpp:374
void get_sizes(size_t *classrefsize, size_t *descsize)
Definition: descriptor.cpp:961
Iterator end()
Definition: hashtable.hpp:453
paramdesc * params
Definition: descriptor.hpp:164
void descriptor_debug_print_paramdesc(FILE *file, paramdesc *d)
bool check_return_descriptor()
Definition: descriptor.cpp:160
bool parse_field_descriptor(typedesc *dst)
Definition: descriptor.cpp:166
size_t size() const
Definition: utf8.hpp:161
classinfo * get_referer()
Definition: descriptor.cpp:945
Entry & insert(const T &t)
Definition: hashtable.hpp:273
Dummy implementation of a mutex.
Definition: mutex-none.hpp:33
bool parse_type(const char *descriptor_type, typedesc *t)
Definition: descriptor.cpp:231
void exceptions_throw_classformaterror(classinfo *c, const char *message,...)
Definition: exceptions.cpp:634
uint8_t u1
Definition: types.hpp:40
T * allocate(size_t size=sizeof(T))
Definition: descriptor.cpp:497
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
bool has_more_params()
Definition: descriptor.cpp:190
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
bool parse_param_descriptor(typedesc *dst)
Definition: descriptor.cpp:169
const char * end
Definition: descriptor.cpp:146
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
#define CLASSREFHASH_INIT_SIZE
Definition: descriptor.cpp:473
constant_classref * lookup_classref(Utf8String classname)
Definition: descriptor.cpp:657
const char * descriptor_type
Definition: descriptor.cpp:145
bool add_field(Utf8String desc)
Definition: descriptor.cpp:543
bool start_param_list()
Definition: descriptor.cpp:176
PrimitiveType
JVM types.
Definition: primitive.hpp:55
const char * pos
Definition: descriptor.cpp:146
bool check_param_descriptor(Type &dst)
Definition: descriptor.cpp:157
bool throw_error(const char *reason,...)
throws a classformat error and returns false
Definition: descriptor.cpp:454
bool parse_return_descriptor(typedesc *dst)
Definition: descriptor.cpp:172
Type
Types used internally by JITTED code.
Definition: global.hpp:117
bool is_valid_name() const
Definition: utf8.cpp:393
void exceptions_throw_internalerror(const char *message,...)
Definition: exceptions.cpp:805
Mutex * pool_lock
Definition: descriptor.hpp:165
#define MMOVE(dest, src, type, num)
Definition: memory.hpp:106
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
MIIterator i
typedesc returntype
Definition: descriptor.hpp:166
FieldrefHash fieldrefhash
Definition: descriptor.hpp:109
int32_t s4
Definition: types.hpp:45
MIIterator pos
Type descriptor_to_basic_type(Utf8String descriptor)
Definition: descriptor.cpp:978
void md_param_alloc(methoddesc *md)
Definition: md-abi.cpp:153
static Mutex mutex
Definition: show.cpp:73
void params_from_paramtypes(s4 mflags)
Definition: descriptor.cpp:877
size_t size()
Definition: hashtable.hpp:457
bool inmemory
Definition: descriptor.hpp:151
void utf_fprint_printable_ascii(FILE *file, Utf8String u)
Definition: utf8.cpp:650
#define METHODDESC_NOPARAMS
Definition: descriptor.hpp:184
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
void md_param_alloc_native(methoddesc *md)
Definition: md-abi.cpp:224
typedesc * parse_field_descriptor(Utf8String desc)
Definition: descriptor.cpp:708
EntryRef find(const T &t)
Definition: hashtable.hpp:215
ssize_t add_method(Utf8String desc)
Definition: descriptor.cpp:576
#define MNEW(type, num)
Definition: memory.hpp:96
bool parse_classname(Utf8String &classname)
Definition: descriptor.cpp:353
uint8_t * descriptors_next
Definition: descriptor.hpp:122
Buffer & writevf(const char *fmt, va_list ap)
Definition: buffer.hpp:438
Buffer & write(char)
Definition: buffer.hpp:280
constant_classref * classrefs
Definition: descriptor.hpp:116
methoddesc * parse_method_descriptor(Utf8String desc, s4 mflags, constant_classref *thisclass)
Definition: descriptor.cpp:751
Iterator begin()
Definition: hashtable.hpp:442
int16_t s2
Definition: types.hpp:42
bool check_field_descriptor()
Definition: descriptor.cpp:152
ClassrefHash classrefhash
Definition: descriptor.hpp:108
bool add_class(Utf8String name)
Definition: descriptor.cpp:511
void descriptor_debug_print_typedesc(FILE *file, typedesc *d)
void descriptor_debug_print_methoddesc(FILE *file, methoddesc *d)
#define str(x)
PrimitiveType primitivetype
Definition: descriptor.hpp:137
constant_classref * create_classrefs(s4 *count)
Definition: descriptor.cpp:630
DescriptorParser(DescriptorPool *pool, Utf8String desc)
Definition: descriptor.cpp:149
uint32_t regoff
Definition: descriptor.hpp:153
const Utf8String name
Definition: references.hpp:48
#define FIELDREFHASH_INIT_SIZE
Definition: descriptor.cpp:476
constant_classref * classref
Definition: descriptor.hpp:135
bool has_more_input() const
Definition: descriptor.cpp:201
bool read(char &)
Definition: descriptor.cpp:442
DescriptorPool *const pool
Definition: descriptor.cpp:144