aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: * aoqi@0: */ aoqi@0: aoqi@0: #include "precompiled.hpp" aoqi@0: #include "classfile/systemDictionary.hpp" aoqi@0: #include "memory/oopFactory.hpp" aoqi@0: #include "oops/oop.inline.hpp" aoqi@0: #include "oops/typeArrayKlass.hpp" aoqi@0: #include "runtime/fieldType.hpp" aoqi@0: #include "runtime/signature.hpp" aoqi@0: aoqi@0: void FieldType::skip_optional_size(Symbol* signature, int* index) { aoqi@0: jchar c = signature->byte_at(*index); aoqi@0: while (c >= '0' && c <= '9') { aoqi@0: *index = *index + 1; aoqi@0: c = signature->byte_at(*index); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: BasicType FieldType::basic_type(Symbol* signature) { aoqi@0: return char2type(signature->byte_at(0)); aoqi@0: } aoqi@0: aoqi@0: // Check if it is a valid array signature aoqi@0: bool FieldType::is_valid_array_signature(Symbol* sig) { aoqi@0: assert(sig->utf8_length() > 1, "this should already have been checked"); aoqi@0: assert(sig->byte_at(0) == '[', "this should already have been checked"); aoqi@0: // The first character is already checked aoqi@0: int i = 1; aoqi@0: int len = sig->utf8_length(); aoqi@0: // First skip all '['s aoqi@0: while(i < len - 1 && sig->byte_at(i) == '[') i++; aoqi@0: aoqi@0: // Check type aoqi@0: switch(sig->byte_at(i)) { aoqi@0: case 'B': // T_BYTE aoqi@0: case 'C': // T_CHAR aoqi@0: case 'D': // T_DOUBLE aoqi@0: case 'F': // T_FLOAT aoqi@0: case 'I': // T_INT aoqi@0: case 'J': // T_LONG aoqi@0: case 'S': // T_SHORT aoqi@0: case 'Z': // T_BOOLEAN aoqi@0: // If it is an array, the type is the last character aoqi@0: return (i + 1 == len); aoqi@0: case 'L': aoqi@0: // If it is an object, the last character must be a ';' aoqi@0: return sig->byte_at(len - 1) == ';'; aoqi@0: } aoqi@0: aoqi@0: return false; aoqi@0: } aoqi@0: aoqi@0: aoqi@0: BasicType FieldType::get_array_info(Symbol* signature, FieldArrayInfo& fd, TRAPS) { aoqi@0: assert(basic_type(signature) == T_ARRAY, "must be array"); aoqi@0: int index = 1; aoqi@0: int dim = 1; aoqi@0: skip_optional_size(signature, &index); aoqi@0: while (signature->byte_at(index) == '[') { aoqi@0: index++; aoqi@0: dim++; aoqi@0: skip_optional_size(signature, &index); aoqi@0: } aoqi@0: ResourceMark rm; aoqi@0: char *element = signature->as_C_string() + index; aoqi@0: BasicType element_type = char2type(element[0]); aoqi@0: if (element_type == T_OBJECT) { aoqi@0: int len = (int)strlen(element); aoqi@0: assert(element[len-1] == ';', "last char should be a semicolon"); aoqi@0: element[len-1] = '\0'; // chop off semicolon aoqi@0: fd._object_key = SymbolTable::new_symbol(element + 1, CHECK_(T_BYTE)); aoqi@0: } aoqi@0: // Pass dimension back to caller aoqi@0: fd._dimension = dim; aoqi@0: return element_type; aoqi@0: }