gecko-dev/ef/Utilities/qa/constantpool/AttributeHandlers.cpp

415 строки
9.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "AttributeHandlers.h"
#ifndef NO_NSPR
#include "plstr.h"
#endif
/* Implementation of class AttributeHandler */
AttributeHandler::AttributeHandler(Pool &pool, FileReader *_reader,
ClassFileReader *_cfr,
const char *_name):
p(pool), name(_name), reader(_reader), cfr(_cfr)
{
constantPool = (ConstantPoolItem **) cfr->getConstantPool();
constantPoolCount = cfr->getConstantPoolCount();
}
int AttributeHandler::validateNameAndLength(const char *_name,
uint32 *length,
CrError *status) {
*status = crErrorNone;
#ifdef NO_NSPR
if (_name && name && strcmp(name, _name) != 0)
#else
if (_name && name && PL_strcmp(name, _name) != 0)
#endif
return false;
/* Get the length */
if (!reader->readU4(length, 1)) {
*status = crErrorIO;
return false;
}
return true;
}
#define READ_INDEX(index) \
uint16 index;\
if (!reader->readU2(&index, 1)) {\
*status = crErrorIO;\
return 0;\
}
/* Implementation of AttributeHandlerSourceFile */
AttributeInfoItem *AttributeHandlerSourceFile::handle(const char *_name,
uint16 nindex,
CrError *status)
{
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
READ_INDEX(sourceFileIndex);
if (invalidAttribute(sourceFileIndex, CR_CONSTANT_UTF8)) {
*status = crErrorInvalidAttribute;
return 0;
}
AttributeSourceFile *item =
new (p)
AttributeSourceFile(p, (ConstantUtf8 *) constantPool[sourceFileIndex],
sourceFileIndex, nindex);
return item;
}
/* Implementation of AttributeHandlerConstantValue */
AttributeInfoItem *AttributeHandlerConstantValue::handle(const char *_name,
uint16 nindex,
CrError *status)
{
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
READ_INDEX(constantValueIndex);
if (invalidIndex(constantValueIndex)) {
*status = crErrorInvalidAttribute;
return 0;
}
int type = constantPool[constantValueIndex]->getType();
/* constantValueIndex must point to a long, float, double,
* integer, or string
*/
if (!((type > 2 && type < 7) ||
(type == CR_CONSTANT_STRING))) {
#ifdef DEBUG
printf("Invalid CONSTANT_VALUE attribute: type is %d", type);
#endif
*status = crErrorInvalidAttribute;
return 0;
}
AttributeConstantValue *item = new (p)
AttributeConstantValue(p, constantPool[constantValueIndex],
constantValueIndex, nindex);
return item;
}
/* Implementation of AttributeHandlerCode */
AttributeInfoItem *AttributeHandlerCode::handle(const char *_name,
uint16 nindex,
CrError *status) {
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
uint16 maxStack, maxLocals;
uint32 codeLength;
if (!reader->readU2(&maxStack, 1)) {
*status = crErrorIO;
return 0;
}
if (!reader->readU2(&maxLocals, 1)) {
*status = crErrorIO;
return 0;
}
if (!reader->readU4(&codeLength, 1)) {
*status = crErrorIO;
return 0;
}
#if 0
printf("---> maxStack %d maxLocals %d codeLength %d\n",
maxStack, maxLocals, codeLength);
#endif
AttributeCode *code = new (p) AttributeCode(p, length, maxStack,
maxLocals, codeLength,
nindex,
status);
if (*status != crErrorNone)
return 0;
char *codeStr = (char *) code->getCode();
if (codeLength > 0) {
if (!reader->readU1(codeStr, codeLength)) {
*status = crErrorIO;
return 0;
}
}
#ifdef DEBUG
else {
print(0, "Warning: CODE array has length <= 0 in class %s",
cfr->getThisClass()->getUtf()->getUtfString());
}
#endif
uint16 numExceptions;
if (!reader->readU2(&numExceptions, 1)) {
*status = crErrorIO;
return 0;
}
if (!code->setNumExceptions(numExceptions)) {
*status = crErrorNoMem;
return 0;
}
ExceptionItem **exceptions = code->getExceptions();
for (int i = 0; i < numExceptions; i++) {
uint16 array[4], catchIndex;
/* Read in startPc, endPc, handlerPc, catchType */
if (!reader->readU2(array, 4)) {
*status = crErrorIO;
return 0;
}
if ((catchIndex = array[3]) > 0 && (invalidAttribute(catchIndex,
CR_CONSTANT_CLASS))) {
#ifdef DEBUG
print(0, "AttributeHandlerCode(): invalid catchIndex %d, type %d",
catchIndex, constantPool[catchIndex]->getType());
#endif
*status = crErrorInvalidAttribute;
return 0;
}
if (catchIndex > 0)
exceptions[i] = new (p) ExceptionItem(array[0], array[1], array[2],
(ConstantClass *) constantPool[catchIndex],
catchIndex);
else
exceptions[i] = new (p) ExceptionItem(array[0], array[1], array[2],
0,
0);
}
uint16 attrCount;
/* Ok, so we can have nested attributes here */
if (!reader->readU2(&attrCount, 1)) {
*status = crErrorIO;
return 0;
}
if (!code->setNumAttributes(attrCount)) {
*status = crErrorNoMem;
return 0;
}
AttributeInfoItem **attributes = code->getAttributes();
if ((*status = cfr->readAttributes(attributes, attrCount)) != 0) {
return 0;
}
return code;
}
/* Implementation of AttributeHandlerLineNumberTable */
AttributeInfoItem *AttributeHandlerLineNumberTable::handle(const char *_name,
uint16 nindex,
CrError *status)
{
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
uint16 numEntries;
if (!reader->readU2(&numEntries, 1)) {
*status = crErrorIO;
return 0;
}
AttributeLineNumberTable *table = new (p)
AttributeLineNumberTable(p, length, nindex);
if (!table->setNumEntries(numEntries)) {
*status = crErrorNoMem;
return 0;
}
LineNumberEntry *entries = table->getEntries();
for (int i = 0; i < numEntries; i++) {
uint16 temp[2];
if (!reader->readU2(temp, 2)) {
*status = crErrorNoMem;
return 0;
}
entries[i].startPc = temp[0];
entries[i].lineNumber = temp[1];
}
return table;
}
/* Implementation of AttributeHandlerLocalVariableTable */
AttributeInfoItem *AttributeHandlerLocalVariableTable::handle(const char *_name,
uint16 nindex,
CrError *status)
{
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
uint16 numEntries;
if (!reader->readU2(&numEntries, 1)) {
*status = crErrorIO;
return 0;
}
AttributeLocalVariableTable *table = new (p)
AttributeLocalVariableTable(p, length, nindex);
if (!table->setNumEntries(numEntries)) {
*status = crErrorNoMem;
return 0;
}
LocalVariableEntry *entries = table->getEntries();
for (int i = 0; i < numEntries; i++) {
uint16 temp[5];
if (!reader->readU2(temp, 5)) {
*status = crErrorNoMem;
return 0;
}
entries[i].startPc = temp[0];
entries[i].length = temp[1];
if (invalidAttribute(temp[2], CR_CONSTANT_UTF8)) {
*status = crErrorInvalidConstant;
return 0;
}
entries[i].name = (ConstantUtf8 *) constantPool[temp[2]];
entries[i].nameIndex = temp[2];
if (invalidAttribute(temp[3], CR_CONSTANT_UTF8)) {
*status = crErrorInvalidConstant;
return 0;
}
entries[i].descriptor = (ConstantUtf8 *) constantPool[temp[3]];
entries[i].descIndex = temp[3];
entries[i].index = temp[4];
}
return table;
}
/* Implementation of AttributeHandlerExceptions */
AttributeInfoItem *AttributeHandlerExceptions::handle(const char *_name,
uint16 nindex,
CrError *status)
{
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
uint16 numExceptions;
if (!reader->readU2(&numExceptions, 1)) {
*status = crErrorIO;
return 0;
}
AttributeExceptions *exception = new (p) AttributeExceptions(p, length,
nindex);
ConstantClass **exceptionList;
if (!exception->setNumExceptions(numExceptions)) {
*status = crErrorNoMem;
return 0;
}
exceptionList = exception->getExceptions();
uint16 *excIndices = exception->getExcIndices();
for (int i = 0; i < numExceptions; i++) {
uint16 index;
if (!reader->readU2(&index, 1)) {
*status = crErrorIO;
return 0;
}
if (invalidAttribute(index, CR_CONSTANT_CLASS)) {
*status = crErrorIO;
return 0;
}
exceptionList[i] = (ConstantClass *) constantPool[index];
excIndices[i] = index;
}
return exception;
}
/* Implementation of AttributeHandlerDummy */
AttributeInfoItem *AttributeHandlerDummy::handle(const char *_name,
uint16 nindex,
CrError *status)
{
uint32 length;
if (!validateNameAndLength(_name, &length, status))
return 0;
char *data = new (p) char[length];
/* Read the data */
if (!reader->readU1(data, length)) {
*status = crErrorIO;
return 0;
}
AttributeInfoItem *item = new (p) AttributeInfoItem(p, name, 0, length,
nindex);
return item;
}