changeset 4132:ecd56b400ef3

8157176: Improved classfile parsing Reviewed-by: pliden
author vkempik
date Thu, 30 Jun 2016 23:08:42 +0300
parents 073121aafb67
children 6686cfcf4aa1
files src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/signature.cpp
diffstat 2 files changed, 44 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/runtime/sharedRuntime.cpp	Tue Nov 15 03:00:02 2016 +0000
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Thu Jun 30 23:08:42 2016 +0300
@@ -2779,8 +2779,6 @@
   char *s = sig->as_C_string();
   int len = (int)strlen(s);
   s++; len--;                   // Skip opening paren
-  char *t = s+len;
-  while( *(--t) != ')' ) ;      // Find close paren
 
   BasicType *sig_bt = NEW_RESOURCE_ARRAY( BasicType, 256 );
   VMRegPair *regs = NEW_RESOURCE_ARRAY( VMRegPair, 256 );
@@ -2789,7 +2787,7 @@
     sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature
   }
 
-  while( s < t ) {
+  while( *s != ')' ) {          // Find closing right paren
     switch( *s++ ) {            // Switch on signature character
     case 'B': sig_bt[cnt++] = T_BYTE;    break;
     case 'C': sig_bt[cnt++] = T_CHAR;    break;
--- a/src/share/vm/runtime/signature.cpp	Tue Nov 15 03:00:02 2016 +0000
+++ b/src/share/vm/runtime/signature.cpp	Thu Jun 30 23:08:42 2016 +0300
@@ -224,7 +224,49 @@
   _index = 0;
   expect('(');
   Symbol* sig = _signature;
-  while (sig->byte_at(_index) != ')') _index++;
+  // Need to skip over each type in the signature's argument list until a
+  // closing ')' is found., then get the return type.  We cannot just scan
+  // for the first ')' because ')' is a legal character in a type name.
+  while (sig->byte_at(_index) != ')') {
+    switch(sig->byte_at(_index)) {
+      case 'B':
+      case 'C':
+      case 'D':
+      case 'F':
+      case 'I':
+      case 'J':
+      case 'S':
+      case 'Z':
+      case 'V':
+        {
+          _index++;
+        }
+        break;
+      case 'L':
+        {
+          while (sig->byte_at(_index++) != ';') ;
+        }
+        break;
+      case '[':
+        {
+          int begin = ++_index;
+          skip_optional_size();
+          while (sig->byte_at(_index) == '[') {
+            _index++;
+            skip_optional_size();
+          }
+          if (sig->byte_at(_index) == 'L') {
+            while (sig->byte_at(_index++) != ';') ;
+          } else {
+            _index++;
+          }
+        }
+        break;
+      default:
+        ShouldNotReachHere();
+        break;
+    }
+  }
   expect(')');
   // Parse return type
   _parameter_index = -1;