fieldType.cpp revision 2273:1d1603768966
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41541Srgrimes *
51541Srgrimes * This code is free software; you can redistribute it and/or modify it
61541Srgrimes * under the terms of the GNU General Public License version 2 only, as
71541Srgrimes * published by the Free Software Foundation.
81541Srgrimes *
91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131541Srgrimes * accompanied this code).
141541Srgrimes *
151541Srgrimes * You should have received a copy of the GNU General Public License version
161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181541Srgrimes *
191541Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
201541Srgrimes * or visit www.oracle.com if you need additional information or have any
211541Srgrimes * questions.
221541Srgrimes *
231541Srgrimes */
241541Srgrimes
251541Srgrimes#include "precompiled.hpp"
261541Srgrimes#include "classfile/systemDictionary.hpp"
271541Srgrimes#include "memory/oopFactory.hpp"
281541Srgrimes#include "oops/oop.inline.hpp"
291541Srgrimes#include "oops/typeArrayKlass.hpp"
301541Srgrimes#include "runtime/fieldType.hpp"
311541Srgrimes#include "runtime/signature.hpp"
321541Srgrimes
331541Srgrimesvoid FieldType::skip_optional_size(Symbol* signature, int* index) {
345109Swollman  jchar c = signature->byte_at(*index);
351541Srgrimes  while (c >= '0' && c <= '9') {
361541Srgrimes    *index = *index + 1;
372169Spaul    c = signature->byte_at(*index);
382169Spaul  }
392169Spaul}
401541Srgrimes
411541SrgrimesBasicType FieldType::basic_type(Symbol* signature) {
421541Srgrimes  return char2type(signature->byte_at(0));
431541Srgrimes}
441541Srgrimes
451541Srgrimes// Check if it is a valid array signature
461541Srgrimesbool FieldType::is_valid_array_signature(Symbol* sig) {
471541Srgrimes  assert(sig->utf8_length() > 1, "this should already have been checked");
481541Srgrimes  assert(sig->byte_at(0) == '[', "this should already have been checked");
491541Srgrimes  // The first character is already checked
501541Srgrimes  int i = 1;
511541Srgrimes  int len = sig->utf8_length();
521541Srgrimes  // First skip all '['s
531541Srgrimes  while(i < len - 1 && sig->byte_at(i) == '[') i++;
541541Srgrimes
551541Srgrimes  // Check type
561541Srgrimes  switch(sig->byte_at(i)) {
571541Srgrimes    case 'B': // T_BYTE
582531Swollman    case 'C': // T_CHAR
591541Srgrimes    case 'D': // T_DOUBLE
601541Srgrimes    case 'F': // T_FLOAT
611541Srgrimes    case 'I': // T_INT
621541Srgrimes    case 'J': // T_LONG
631541Srgrimes    case 'S': // T_SHORT
641541Srgrimes    case 'Z': // T_BOOLEAN
651541Srgrimes      // If it is an array, the type is the last character
661541Srgrimes      return (i + 1 == len);
671541Srgrimes    case 'L':
681541Srgrimes      // If it is an object, the last character must be a ';'
691541Srgrimes      return sig->byte_at(len - 1) == ';';
701541Srgrimes  }
711541Srgrimes
721541Srgrimes  return false;
731541Srgrimes}
741541Srgrimes
751541Srgrimes
761541SrgrimesBasicType FieldType::get_array_info(Symbol* signature, FieldArrayInfo& fd, TRAPS) {
771541Srgrimes  assert(basic_type(signature) == T_ARRAY, "must be array");
781541Srgrimes  int index = 1;
791541Srgrimes  int dim   = 1;
801541Srgrimes  skip_optional_size(signature, &index);
811541Srgrimes  while (signature->byte_at(index) == '[') {
821541Srgrimes    index++;
831541Srgrimes    dim++;
841541Srgrimes    skip_optional_size(signature, &index);
851541Srgrimes  }
861541Srgrimes  ResourceMark rm;
871541Srgrimes  char *element = signature->as_C_string() + index;
881541Srgrimes  BasicType element_type = char2type(element[0]);
891541Srgrimes  if (element_type == T_OBJECT) {
901541Srgrimes    int len = (int)strlen(element);
911541Srgrimes    assert(element[len-1] == ';', "last char should be a semicolon");
921541Srgrimes    element[len-1] = '\0';        // chop off semicolon
931541Srgrimes    fd._object_key = SymbolTable::new_symbol(element + 1, CHECK_(T_BYTE));
941541Srgrimes  }
951541Srgrimes  // Pass dimension back to caller
961541Srgrimes  fd._dimension = dim;
971541Srgrimes  return element_type;
981541Srgrimes}
991541Srgrimes